ASP.NET WebAPI: cómo realizar una publicación de varias partes con carga de archivos utilizando WebAPI HttpClient


Tengo un servicio WebAPI que maneja una carga desde un formulario simple, como este:

    <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 imaginar cómo simular el mismo post usando la API HttpClient. El bit FormUrlEncodedContent es bastante simple, pero ¿cómo agrego el contenido del archivo con el nombre a la publicación?

Author: Cheeso, 2012-04-26

3 answers

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;
    }
}
 115
Author: Michael Teper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-05 07:12:08

Necesitas buscar varias subclases de HttpContent.

Se crea un contenido http multiforme y se le agregan varias partes. En su caso, tiene un contenido de matriz de bytes y una url de formulario codificada a 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);
 10
Author: Aliostad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-27 00:06:57

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.

 8
Author: ThiagoPXP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-03 00:34:05