7

フォームデータを追加してファイルをアップロードしようとしていますが、MVC経由でWeb APIに投稿していますが、できませんでした。MVCのWeb APIにAdditonalフォームデータをアップロードするファイル

MVCサイド

まず私はMVCで送信されたフォームを得ました。ここにこれのための行動があります。ウェブAPI

string requestUri = UriUtil.BuildRequestUri(_baseUri, uriTemplate, uriParameters: uriParameters); 
      MultipartFormDataContent formData = new MultipartFormDataContent(); 
      StreamContent streamContent = null; 
      streamContent = new StreamContent(new MemoryStream(byteData));    
      streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { 
       FileName = "\"" + fileName + "\"", 
       Name = "\"filename\"" 
      }; 
      streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
      formData.Add(streamContent); 
      formData.Add(new ObjectContent<TRequestModel>(requestModel, _writerMediaTypeFormatter), "entity"); 
      return _httpClient.PutAsync(requestUri, formData).GetHttpApiResponseAsync<TResult>(_formatters); 

あなたは、私が同じMultipartFormDataContentとファイルデータとオブジェクトを送信しようとしています見ることができるように、コードのポストMultipartform以下

[HttpPost] 
      public async Task<ActionResult> Edit(BrandInfo entity) { 

       try { 
        byte[] logoData = null; 
        if(Request.Files.Count > 0) { 
         HttpPostedFileBase logo = Request.Files[0]; 
         logoData = new byte[logo.ContentLength]; 
         logo.InputStream.Read(logoData, 0, logo.ContentLength); 
         entity.Logo = logo.FileName; 
         entity = await _repo.Update(entity.BrandID, entity, logoData); 
        } 
        else 
         entity = await _repo.Update(entity,entity.BrandID); 
        return RedirectToAction("Index", "Brand"); 
       } 
       catch(HttpApiRequestException e) { 
// logging, etc     
        return RedirectToAction("Index", "Brand"); 
       } 
      } 

。私はエンティティをObjectContentとして送信するためのより良い方法を見つけることができませんでした。また、私はJSON.Netシリアライザを使用しています

投稿については、投稿がうまくいっているようです。

PUT http://localhost:12836/api/brand/updatewithlogo/13 HTTP/1.1 
Content-Type: multipart/form-data; boundary="10255239-d2a3-449d-8fad-2f31b1d00d2a" 
Host: localhost:12836 
Content-Length: 4341 
Expect: 100-continue 

--10255239-d2a3-449d-8fad-2f31b1d00d2a 
Content-Disposition: form-data; filename="web-host-logo.gif"; name="filename" 
Content-Type: application/octet-stream 

GIF89a��L������X�������wW����������xH�U�)�-�k6�������v6�������̥�v�J���������7����V:�=#�ի�I(�xf�$������� 
// byte data 
// byte data 
'pf�Y��y�ؙ�ڹ�(�; 
--10255239-d2a3-449d-8fad-2f31b1d00d2a 
Content-Type: application/json; charset=utf-8 
Content-Disposition: form-data; name=entity 

{"BrandID":13,"AssetType":null,"AssetTypeID":2,"Logo":"web-host-logo.gif","Name":"Geçici Brand","Models":null,"SupplierBrands":null} 
--10255239-d2a3-449d-8fad-2f31b1d00d2a-- 

ウェブAPIサイド

最後に私は、Web API側のポストをキャッチし、解析しようが、私はできなかったのです。 MultipartFormDataStreamProviderFileDataFormDataのコレクションは常に空です。

[HttpPut] 
     public void UpdateWithLogo(int id) { 
      if(Request.Content.IsMimeMultipartContent()) { 
       var x = 1; // this code has no sense, only here to check IsMimeMultipartContent 
      } 

      string root = HttpContext.Current.Server.MapPath("~/App_Data"); 
      var provider = new MultipartFormDataStreamProvider(root); 

      try { 
       // Read the form data. 
       Request.Content.ReadAsMultipartAsync(provider); 

       foreach(var key in provider.FormData.AllKeys) { 
        foreach(var val in provider.FormData.GetValues(key)) { 
         _logger.Info(string.Format("{0}: {1}", key, val)); 
        } 
       } 

       // This illustrates how to get the file names. 
       foreach(MultipartFileData file in provider.FileData) { 
        _logger.Info(file.Headers.ContentDisposition.FileName); 
        _logger.Info("Server file path: " + file.LocalFileName); 
       }    
      } 
      catch(Exception e) { 
       throw new HttpApiRequestException("Error", HttpStatusCode.InternalServerError, null); 
      }    
     } 

私の間違いを見つけるのを助けてくれることを願っています。

UPDATE

また、私はStreamContentまたはObjectContentをコメントアウトしてのみStringContentを追加した場合、まだ私はMultipartFormDataStreamProviderから何かを得ることができない、ということに気づきました。

+0

私は若干異なる問題に遭遇しました。ブラウザはリクエストから自分の名前/ IDを渡すまでファイルを削除していました。しかし、これは問題の診断に多くの助けとなりました – brichins

答えて

5

は、最後に私は私の問題を解決し、それがすべてについて非同期た:)

あなたは私がsynchrously ReadAsMultipartAsyncメソッドを呼び出していたが、これは間違いだったAPIのアクションメソッドで見ることができるように。私はContinueWithと呼ぶ必要があったので、私の問題を解決した私のコードを変更した後。

var files = Request.Content.ReadAsMultipartAsync(provider).ContinueWith<HttpResponseMessage>(task => { 
        if(task.IsFaulted) 
         throw task.Exception; 
// do additional stuff 
}); 
+0

これで問題が解決した場合は、それを受け入れたものとしてマークしてください。 – anaximander

+0

ああ、私はその制限を忘れていました。 – anaximander

+1

すみません、私はちょっと混乱しています。タスクは正確に何ですか?私はここでもフォームデータを持っていなければなりませんか? – Bobby5193

関連する問題