7

Ich versuche, eine Datei mit zusätzlichen Formulardaten hochladen und auf Web-API über MVC, aber ich konnte nicht erreichen.Datei-Upload mit zusätzlichen Formulardaten zu Web-API von MVC

MVC Side

Zum einen habe ich die bei MVC eingereicht Form. Hier ist die Aktion dafür.

[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"); 
       } 
      } 

Below Code Beitrag der Multipartform zu Web 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); 

Wie man sehen kann ich versuche, Dateidaten und Objekt mit dem gleichen MultipartFormDataContent zu senden. Ich konnte keinen besseren Weg finden, meine Entität als ObjectContent zu senden. Auch ich benutze JSON.Net Serializer

In Bezug auf Fiddler scheint Post erfolgreich.

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-- 

Web API Side

Schließlich i Post an Web-API-Seite am Fang und versuchen zu analysieren, aber ich kann es nicht. Denn die MultipartFormDataStreamProvider 's FileData und FormData Sammlungen sind immer leer.

[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); 
      }    
     } 

Ich hoffe, Sie können helfen, meinen Fehler zu finden.

UPDATE

Ich erkannte auch, dass, wenn ich StreamContent oder ObjectContent Kommentar und nur StringContent hinzufügen, ich habe noch nichts von MultipartFormDataStreamProvider bekommen kann.

+0

Ich stieß auf ein etwas anderes Problem - der Browser ließ meine Dateien von der Anfrage fallen, bis ich ihnen einen Namen/eine ID gab. Dies half sehr bei der Diagnose des Problems durch – brichins

Antwort

5

Schließlich beschloss ich mein Problem, und es war alles über async :)

Wie Sie bei API Aktion Methode sehen kann ich synchron dazu ReadAsMultipartAsync Methode genannt hatte, aber das war ein Fehler. Ich musste es mit ContinueWith anrufen, also nachdem ich meinen Code wie unten geändert habe, löste sich mein Problem.

+0

Wenn das Problem behoben wurde, markieren Sie es als akzeptiert. – anaximander

+0

Ah, ich habe diese Einschränkung vergessen. – anaximander

+1

Es tut mir leid, ich bin ein wenig verwirrt hier. Was genau ist die Aufgabe? und sollte ich auch hier die Formulardaten haben? – Bobby5193