2016-07-23 118 views
1

我得到415(Unsupported Media Type)當我嘗試將圖像發佈到ASP.Net API 2 請求實體的媒體類型'multipart/form-data'是不支持此資源。「,」exceptionMessage「:」沒有MediaTypeFormatter可用於從媒體類型爲「multipart/form-data」的內容中讀取'Attachment'類型的對象。post image to asp.net API 2 and angular 2

我的後端Post方法:

[HttpPost] 
    [Route("api/listing/{listingId}/Attachment/")] 
    public async Task<dynamic> Post([FromBody] Attachment model) 
    { 

     var Attachments = new Attachment 
     { 

      ListingId = model.ListingId, 
      Content = model.Content, 
      Description = model.Description, 
      Name = model.Name, 
      MimeType = model.MimeType, 
      Size = model.Size, 
      CreatedOn = DateTime.UtcNow, 
      UpdatedOn = model.UpdatedOn, 
     }; 

     return await DataStore.InsertDynamicAsync(Attachments); 
    } 

我的前端方法:

onChangeImage(e: any) { 
     console.log(this.className + 'onChangeImage.event=' +JSON.stringify(event)); 
console.log(this.className + 'onChangeImage._listingAttachmentService undefined?: ' + (this._listingAttachmentService === undefined)); 
const inputElement = this.fileInput.nativeElement; 

const fileList = inputElement.files; 
const files = []; 
console.log('AttachmentsTabComponent: file count = ' + fileList.length); 

if (fileList.length > 0) { 

    for (let i = 0; i < fileList.length; i++) { 

    // get item 
    const file = fileList.item(i); 
    files.push(file); 
    const model: Attachment = { 
     listingId: this.listing.id, 

     mimeType: file.type, 
     name: file.name, 
     size: file.size, 
     updatedOn: file.lastModifiedDate 
    }; 



    const reader = new FileReader(); 
    reader.readAsDataURL(file); 

    console.log(this.className + 'onChangeImage.listingAttachmentService (before reader.onload) undefined?: ' + (this._listingAttachmentService === undefined)); 

    reader.onload = (readerEvt: any) => { 
     const binaryString = readerEvt.target.result; 

     //base-64 encoded ASCII string 
     model.content = btoa(binaryString); 

     console.log(this.className + 'onChangeImage.listingAttachmentService (during reader.onload) undefined?: ' + (this._listingAttachmentService === undefined)); 

     console.log(this.className + 'ListingAttachmentModel.content.length=' + JSON.stringify(model.content.length)); 
     // this._listingAttachmentService.add(model); 
    }; 
    } 

    // try to clear the file input 
    try { 
    // TODO: fix this 
    this.fileForm.nativeElement.reset(); 
    inputElement.value = ''; 
    if (inputElement.value) { 
     inputElement.type = 'text'; 
     inputElement.type = 'file'; 
    } 
    } catch (e) { } 

    this._listingAttachmentService.upload(this.listing.id, files) 
    .subscribe(data => { 
     this.listing.attachments = data; 
    }); 
} 
    } 

和我listingAttachmentService

upload(listingId: number, files: Array<File>) { 

this._logger.debug('method upload() entered'); 
this._logger.debug('upload() listingId=' + listingId); 
this._logger.debug('this.fileToUpload.length=' + files.length); 

var self = this; 

return Observable.create(observer => { 
    console.log('creating Observable'); 
    let formData: FormData = new FormData(), 
    xhr: XMLHttpRequest = new XMLHttpRequest(); 

    formData.append('listingId', listingId); 
    for (let i = 0; i < files.length; i++) { 
    formData.append('uploads[]', files[i], files[i].name); 
    } 

    xhr.onreadystatechange =() => { 
    if (xhr.readyState === 4) { 
     if (xhr.status === 200) { 
     observer.next(JSON.parse(xhr.response)); 
     observer.complete(); 
     } else { 
     observer.error(xhr.response); 
     } 
    } 
    }; 

    let newbaseUrl = self.baseUrl + listingId + '/attachment/' ; 
    xhr.open('POST', newbaseUrl, true); 
    xhr.send(formData); 
}) 
    .catch(this.handleError); 
} 
+0

你可以檢查我的答案。 –

回答

1

你應該使用自定義MediaTypeFormatter 。點擊此處瞭解詳情:http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters這裏http://blog.marcinbudny.com/2014/02/sending-binary-data-along-with-rest-api.html#.V5MDDzV7qYg

public class CustomFormatter : MediaTypeFormatter 
    { 
     public CustomFormatter() 
     { 
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data")); 
     } 

     public override bool CanReadType(Type type) 
     { 
      return type == typeof(Attachment); 
     } 

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

     public async override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) 
     { 
      var provider = await content.ReadAsMultipartAsync(); 

      var modelContent = provider.Contents 
       .FirstOrDefault(c => c.Headers.ContentType.MediaType == "application/json"); // Can also use ContentDisposition.Name.Normalize == "attachment" 

      var attachment = await modelContent.ReadAsAsync<Attachment>(); 

      var fileContents = provider.Contents 
       .Where(c => c.Headers.ContentType.MediaType == "image/jpeg").FirstOrDefault(); // can also use ContentDisposition.Name.Normalize() == "image" 

      attachment.Content = await fileContents.ReadAsByteArrayAsync(); 

      return attachment; 

     } 
    } 

樣本註冊自定義媒體格式:

private void ConfigureWebApi(HttpConfiguration config) 
{ 
    //other code here 
    config.Formatters.Add(new CustomFormatter()); 
} 

一個帖子會喜歡下面

POST http://localhost/api/FileUpload HTTP/1.1 
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468 
User-Agent: Fiddler 
Content-Length: 88778 

---------------------------acebdf13572468 
Content-Type: application/json; charset=utf-8 
Content-Disposition: form-data; name=attachment 

{"ListingId":"testl"} 
---------------------------acebdf13572468 
Content-Disposition: form-data; name=image; filename=image.jpg 
Content-Type: image/jpeg 

Image content 
---------------------------acebdf13572468-- 

希望這有助於。

+0

我檢查了你的答案,但我得到500內部服務器錯誤,錯誤消息**發生了錯誤。「, 」exceptionMessage「:」未將對象引用設置爲對象的實例** – kero

+0

任何想法哪條線正在拋出那個錯誤? –

+0

「stackTrace」:「at OutdoorAccess.Api.Utilities.CustomFormatter。<> c。 b__3_0(HttpContent c)in C:\\ Users \\ keroles.hakem \\ Documents \\ mvp \\ web-api \ \ OutdoorAccess.Api \\ Utilities \\ CustomFormatter.cs:位於OutdoorAccess.Api的System.Linq.Enumerable.FirstOrDefault [TSource](IEnumerable'1 source,Func'2謂詞)\ r \ n的第36行\ r \ n。 Utilities.CustomFormatter。 d__3.MoveNext()in C:\\ Users \\ keroles.hakem \\ Documents \\ mvp \\ web-api \\ OutdoorAccess.Api \\ Utilities \\ CustomFormatter.cs:line 35 \ r \ n ---堆棧跟蹤結束.... } – kero