2017-10-21 3 views
4

내가 코어 2 ASP.NET에 ASP.NET MVC 5에서 프로젝트를 마이그레이션하는 과정에서이고 지금까지 내가 말할 수있는대로 MultipartFormDataStreamProviderMultipartFormDataStreamProvider에 대한 ASP.NET 코어 2

에 관한 몇 가지 문제로 실행 한 아직 .NET Core의 일부가 아니므로 사용할 수 없습니다. 내가 해결하려고하는 문제는 Sendgrid가 전자 메일의 구문 분석에 사용되는 코드의 일부입니다. 그래서 https://sendgrid.com/docs/Integrate/Code_Examples/Webhook_Examples/csharp.html

내가하려고 잠시 동안이 바이올린을 켜는되었습니다이 코드는 Sendgrid의 API 문서에서 가져온 조각입니다

[HttpPost] 
public async Task<HttpResponseMessage> Post() 
{ 
    var root = HttpContext.Current.Server.MapPath("~/App_Data"); 
    var provider = new MultipartFormDataStreamProvider(root); 
    await Request.Content.ReadAsMultipartAsync(provider); 

    var email = new Email 
    { 
     Dkim = provider.FormData.GetValues("dkim").FirstOrDefault(), 
     To = provider.FormData.GetValues("to").FirstOrDefault(), 
     Html = provider.FormData.GetValues("html").FirstOrDefault() 
    } 
} 

다음과 같이

닷넷 MVC (5) 코드가 보인다 해결책을 제안해라. 그렇지 않으면 나는 완전히 붙어있다. 내가 왔어요 솔루션에 가장 가까운 크롬에 대한 ARC REST 클라이언트 플러그인 (또는 다른 REST-API 테스터)를 통해 데이터를 보낼 때 Request.Form 예컨대

To = form["to"].SingleOrDefault(), 
From = form["from"].SingleOrDefault() 

그러나이 단지 작품을 사용하는 것입니다. 또한이 솔루션은 이미지와 같은 첨부 파일을 처리 할 수 ​​없습니다.

그래서 나는 누군가가 어떤 포인터 또는 사전에 .NET 코어에 2

덕분에이를 마이그레이션하는 방법에 대한 해결책을 가지고 희망에 StackOverflow의 커뮤니티에 돌리겠다!

+0

sendgrid에 V3 API를 사용하고 있습니까? sendgrid C# sdk는 여전히 .net core 2.0을 지원하지 않습니다. – Niladri

+0

Request.Form.Files를 보셨습니까? – Tratcher

답변

1

여기까지 내 솔루션입니다. 첨부 파일을 처리하는 것과 같이 여전히 진행중인 작업이지만 이메일을 성공적으로 파싱합니다.

그것은 https://dotnetcoretutorials.com/2017/03/12/uploading-files-asp-net-core/

[HttpPost] 
    [DisableFormValueModelBinding] 
    [Route("v4/ProcessEmail")] 
    public async Task<IActionResult> ParseSendGridInboundWebHook() 
    { 
     FormValueProvider formModel; 
     using (var stream = System.IO.File.Create("c:\\temp\\myfile.temp")) 
     { 
      formModel = await _context.HttpContext.Request.StreamFile(stream); 
     } 

     var viewModel = new SendGridEmailDTO(); 

     var bindingSuccessful = await TryUpdateModelAsync(viewModel, prefix: "", 
      valueProvider: formModel); 

     if (!bindingSuccessful) 
     { 
      if (!ModelState.IsValid) 
      { 
       return new BadRequestResult(); 
      } 
     } 


     <your code here> 

     return new OkResult(); 

    } 


public static class MultipartRequestHelper 
{ 
    // Content-Type: multipart/form-data; boundary="----WebKitFormBoundarymx2fSWqWSd0OxQqq" 
    // The spec says 70 characters is a reasonable limit. 
    public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit) 
    { 
     var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary); 
     if (string.IsNullOrWhiteSpace(boundary.Value)) 
     { 
      throw new InvalidDataException("Missing content-type boundary."); 
     } 

     if (boundary.Length > lengthLimit) 
     { 
      throw new InvalidDataException(
       $"Multipart boundary length limit {lengthLimit} exceeded."); 
     } 

     return boundary.Value; 
    } 

    public static bool IsMultipartContentType(string contentType) 
    { 
     return !string.IsNullOrEmpty(contentType) 
       && contentType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0; 
    } 

    public static bool HasFormDataContentDisposition(ContentDispositionHeaderValue contentDisposition) 
    { 
     // Content-Disposition: form-data; name="key"; 
     return contentDisposition != null 
       && contentDisposition.DispositionType.Equals("form-data") 
       && string.IsNullOrEmpty(contentDisposition.FileName.Value) 
       && string.IsNullOrEmpty(contentDisposition.FileNameStar.Value); 
    } 

    public static bool HasFileContentDisposition(ContentDispositionHeaderValue contentDisposition) 
    { 
     // Content-Disposition: form-data; name="myfile1"; filename="Misc 002.jpg" 
     return contentDisposition != null 
       && contentDisposition.DispositionType.Equals("form-data") 
       && (!string.IsNullOrEmpty(contentDisposition.FileName.Value) 
        || !string.IsNullOrEmpty(contentDisposition.FileNameStar.Value)); 
    } 
} 


public static class FileStreamingHelper 
{ 
    private static readonly FormOptions _defaultFormOptions = new FormOptions(); 

    public static async Task<FormValueProvider> StreamFile(this HttpRequest request, Stream targetStream) 
    { 
     if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType)) 
     { 
      throw new Exception($"Expected a multipart request, but got {request.ContentType}"); 
     } 

     // Used to accumulate all the form url encoded key value pairs in the 
     // request. 
     var formAccumulator = new KeyValueAccumulator(); 
     string targetFilePath = null; 

     var boundary = MultipartRequestHelper.GetBoundary(
      MediaTypeHeaderValue.Parse(request.ContentType), 
      _defaultFormOptions.MultipartBoundaryLengthLimit); 
     var reader = new MultipartReader(boundary, request.Body); 

     var section = await reader.ReadNextSectionAsync(); 
     while (section != null) 
     { 
      var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); 

      if (hasContentDispositionHeader) 
      { 
       if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition)) 
       { 
        await section.Body.CopyToAsync(targetStream); 
       } 
       else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition)) 
       { 
        // Content-Disposition: form-data; name="key" 
        // 
        // value 

        // Do not limit the key name length here because the 
        // multipart headers length limit is already in effect. 
        var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name); 
        var encoding = GetEncoding(section); 
        using (var streamReader = new StreamReader(
         section.Body, 
         encoding, 
         detectEncodingFromByteOrderMarks: true, 
         bufferSize: 1024, 
         leaveOpen: true)) 
        { 
         // The value length limit is enforced by MultipartBodyLengthLimit 
         var value = await streamReader.ReadToEndAsync(); 
         if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase)) 
         { 
          value = String.Empty; 
         } 
         formAccumulator.Append(key.Value, value); 

         if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit) 
         { 
          throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded."); 
         } 
        } 
       } 
      } 

      // Drains any remaining section body that has not been consumed and 
      // reads the headers for the next section. 
      section = await reader.ReadNextSectionAsync(); 
     } 

     // Bind form data to a model 
     var formValueProvider = new FormValueProvider(
      BindingSource.Form, 
      new FormCollection(formAccumulator.GetResults()), 
      CultureInfo.CurrentCulture); 

     return formValueProvider; 
    } 

    private static Encoding GetEncoding(MultipartSection section) 
    { 
     MediaTypeHeaderValue mediaType; 
     var hasMediaTypeHeader = MediaTypeHeaderValue.TryParse(section.ContentType, out mediaType); 
     // UTF-7 is insecure and should not be honored. UTF-8 will succeed in 
     // most cases. 
     if (!hasMediaTypeHeader || Encoding.UTF7.Equals(mediaType.Encoding)) 
     { 
      return Encoding.UTF8; 
     } 
     return mediaType.Encoding; 
    } 
} 


public class SendGridEmailDTO 
{ 
    public string Dkim { get; set; } 
    public string To { get; set; } 
    public string Html { get; set; } 
    public string From { get; set; } 
    public string Text { get; set; } 
    public string SenderIp { get; set; } 
    public string Envelope { get; set; } 
    public int Attachments { get; set; } 
    public string Subject { get; set; } 
    public string Charsets { get; set; } 
    public string Spf { get; set; } 
} 
에서 ASP.NET 코어에서 파일을 업로드에 웨이드의 블로그에서 많이 빌려
+0

['MultipartRequestHeader'] (http://source.dot.net/#System.Net.Http/System/Net/Http/Headers/MediaTypeHeaderValue.cs,9856dc052045cf60) 유형에는 'Boundary'멤버가 없습니다. – Shimmy

+0

알다시피, 우리는'System.Net.Http.Headers'가 아니라'Microsoft.Net.Http.Headers'에 using을 추가해야합니다. – Shimmy