2012-04-26 29 views
51

Tengo un manejo de un proceso de carga de una forma sencilla WebAPI servicio, como éste:ASP.NET WebAPI: cómo realizar un post de varias partes con archivo de carga utilizando WebAPI HttpClient

<form action="/api/workitems" enctype="multipart/form-data" method="post"> 
     <input type="hidden" name="type" value="ExtractText" /> 
     <input type="file" name="FileForUpload" /> 
     <input type="submit" value="Run test" /> 
    </form> 

Sin embargo, no puedo averiguar cómo simular la misma publicación utilizando la API de HttpClient. El bit FormUrlEncodedContent es bastante simple, pero ¿cómo puedo agregar el contenido del archivo con el nombre a la publicación?

+0

¿Te importa compartir el código en el lado de WebApi que consume el contenido de MultipartFormData? – granadaCoder

Respuesta

107

después de mucho ensayo y error, aquí está el código que realmente funciona:

using (var client = new HttpClient()) 
{ 
    using (var content = new MultipartFormDataContent()) 
    { 
     var values = new[] 
     { 
      new KeyValuePair<string, string>("Foo", "Bar"), 
      new KeyValuePair<string, string>("More", "Less"), 
     }; 

     foreach (var keyValuePair in values) 
     { 
      content.Add(new StringContent(keyValuePair.Value), keyValuePair.Key); 
     } 

     var fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(fileName)); 
     fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
     { 
      FileName = "Foo.txt" 
     }; 
     content.Add(fileContent); 

     var requestUri = "/api/action"; 
     var result = client.PostAsync(requestUri, content).Result; 
    } 
} 
+17

Utilice StreamContent para archivos grandes: var fileContenido = new StreamContent (File.OpenRead (fileName)); –

+0

Woohoo - Tenía un problema totalmente diferente, pero necesitaba publicar contenido de todos modos. Pude modificar para adaptarme a mis necesidades. ¡¡Muchas gracias!! –

+3

Extrañamente, esto no funciona para mí. Tuve que agregar citas alrededor de los nombres de contenido, vea esto: http://stackoverflow.com/questions/15638622/how-to-upload-files-to-asp-net-mvc-4-0-action-running-in -iis-express-with-httpcl/15638623 # 15638623 – deerchao

9

Necesita buscar varias subclases de HttpContent.

Crea un contenido http multiforme y le agrega varias partes. En el caso de tener un contenido y forma url matriz de bytes codificados lo largo de las líneas de:

HttpClient c = new HttpClient(); 
var fileContent = new ByteArrayContent(new byte[100]); 
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
              { 
               FileName = "myFilename.txt" 
              }; 

var formData = new FormUrlEncodedContent(new[] 
              { 
               new KeyValuePair<string, string>("name", "ali"), 
               new KeyValuePair<string, string>("title", "ostad") 
              }); 


MultipartContent content = new MultipartContent(); 
content.Add(formData); 
content.Add(fileContent); 
c.PostAsync(myUrl, content); 
+1

Eso no funciona, desafortunadamente, aunque el encabezado 'ContentDisposition' no parece llevarme un paso adelante. Si utilizo el código de muestra tal como está, obtengo una excepción 'Tipo de medio no admitido'. Sin embargo, si reemplazo 'MultipartContent' con' MultipartFormDataContent', la excepción desaparece. En el servidor, sin embargo, falta el valor del campo oculto. –

+0

@MichaelTeper No he probado el código. Jugaré un poco con él y actualizaré la publicación, pero mi objetivo es mostrarte un fragmento de lo que debes buscar y no un código que funcione. – Aliostad

7

Gracias @ Michael Tepper por tu respuesta.

Tuve que enviar archivos adjuntos a MailGun (proveedor de correo electrónico) y tuve que modificarlo ligeramente para que aceptara mis archivos adjuntos.

var fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(fileName)); 
fileContent.Headers.ContentDisposition = 
     new ContentDispositionHeaderValue("form-data") //<- 'form-data' instead of 'attachment' 
{ 
    Name = "attachment", // <- included line... 
    FileName = "Foo.txt", 
}; 
multipartFormDataContent.Add(fileContent); 

Aquí para referencia futura. Gracias.

Cuestiones relacionadas