1

이러한 링크는 나에게 도움이되지 않았다 :ASP.NET 4.5 웹 API에 대한 MultipartFormFormatter을 만드는 방법

예 :

//Model: 
public class Group 
{ 
    public int Id { get; set; }   
    public File File { get; set; } 
} 

//Controller: 
[HttpPost] 
public void SaveGroup([FromBody]Group group) {} 

//Formatter: 
public class MultipartFormFormatter : MediaTypeFormatter 
{ 
    private const string StringMultipartMediaType = "multipart/form-data"; 

    public MultipartFormFormatter() 
    { 
     this.SupportedMediaTypes.Add(new MediaTypeHeaderValue(StringMultipartMediaType)); 

    } 

    public override bool CanReadType(Type type) 
    { 
     return true; 
    } 

    public override bool CanWriteType(Type type) 
    { 
     return false; 
    } 

    public async override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) 
    { 
     //Implementation? What here should be? 
    }  
} 

무엇을해야 방법 ReadFromStreamAsync 반환?

매개 변수를 작업에 적절하게 전송할 수 있도록하려면 어떻게해야합니까?

답변

5
public class MultipartFormFormatter : FormUrlEncodedMediaTypeFormatter 
{ 
    private const string StringMultipartMediaType = "multipart/form-data"; 
    private const string StringApplicationMediaType = "application/octet-stream"; 

    public MultipartFormFormatter() 
    { 
     this.SupportedMediaTypes.Add(new MediaTypeHeaderValue(StringMultipartMediaType)); 
     this.SupportedMediaTypes.Add(new MediaTypeHeaderValue(StringApplicationMediaType)); 
    } 

    public override bool CanReadType(Type type) 
    { 
     return true; 
    } 

    public override bool CanWriteType(Type type) 
    { 
     return false; 
    } 

    public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) 
    { 
     var parts = await content.ReadAsMultipartAsync(); 
     var obj = Activator.CreateInstance(type); 
     var propertiesFromObj = obj.GetType().GetRuntimeProperties().ToList(); 

     foreach (var property in propertiesFromObj.Where(x => x.PropertyType == typeof(FileModel))) 
     { 
      var file = parts.Contents.FirstOrDefault(x => x.Headers.ContentDisposition.Name.Contains(property.Name)); 

      if (file == null || file.Headers.ContentLength <= 0) continue; 

      try 
      { 
       var fileModel = new FileModel(file.Headers.ContentDisposition.FileName, Convert.ToInt32(file.Headers.ContentLength), ReadFully(file.ReadAsStreamAsync().Result)); 
       property.SetValue(obj, fileModel); 
      } 
      catch (Exception e) 
      { 
      } 
     } 

     foreach (var property in propertiesFromObj.Where(x => x.PropertyType != typeof(FileModel))) 
     { 
      var formData = parts.Contents.FirstOrDefault(x => x.Headers.ContentDisposition.Name.Contains(property.Name)); 

      if (formData == null) continue; 

      try 
      { 
       var strValue = formData.ReadAsStringAsync().Result; 
       var valueType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; 
       var value = Convert.ChangeType(strValue, valueType); 
       property.SetValue(obj, value); 
      } 
      catch (Exception e) 
      { 
      } 
     } 

     return obj; 
    } 

    private byte[] ReadFully(Stream input) 
    { 
     var buffer = new byte[16 * 1024]; 
     using (var ms = new MemoryStream()) 
     { 
      int read; 
      while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       ms.Write(buffer, 0, read); 
      } 
      return ms.ToArray(); 
     } 
    } 
} 

public class FileModel 
{ 
    public FileModel(string filename, int contentLength, byte[] content) 
    { 
     Filename = filename; 
     ContentLength = contentLength; 
     Content = content; 
    } 

    public string Filename { get; set; } 

    public int ContentLength { get; set; } 

    public byte[] Content { get; set; } 

} 
+0

감사합니다. 꼬집어서 도와 줬어. 전체 복사/붙여 넣기를 위해'FileModel' 클래스 def를 추가했습니다. 사용법 : 컨트롤러 액션에 대한 인수로 모델에'FileModel' 속성을 추가하고 부트 스트래핑에서'GlobalConfiguration.Configuration.Formatters.Add (new MultipartFormFormatter());'를 잊지 마세요. – jkoreska

2

상세 구현을위한 아래 링크를 참조하십시오 https://github.com/iLexDev/ASP.NET-WebApi-MultipartDataMediaFormatter

Nuget : https://www.nuget.org/packages/MultipartDataMediaFormatter/

실제로 "multipart/form-data"로 파일 업로드 및 모델을 할 필요가

바인딩 오늘, 나는 시도 nuget으로부터의 lib 위에. 그리고 그것은 나의 기대로서 작동한다. 모델의 유효성 검사도 정상적으로 작동합니다. 다행히도 귀하의 질문에 대답하는 것이 도움이됩니다.