Pregunta

¿Cuál es la forma más fácil de enviar una solicitud HTTP POST con un tipo de contenido multipart / form-data desde C #? Tiene que haber una mejor manera que construir mi propia solicitud.

La razón por la que pregunto es para subir fotos a Flickr usando esta API:

http://www.flickr.com/services/api/upload. api.html

¿Fue útil?

Solución

En primer lugar, no hay nada de malo con la implementación manual pura de los comandos HTTP utilizando el marco .Net. Tenga en cuenta que es un marco, y se supone que es bastante genérico.

En segundo lugar, creo que puedes intentar buscar una implementación de navegador en .Net. Vi éste , tal vez cubra el problema que preguntaste acerca de. O simplemente puede buscar " C # http get get post request " ;. Uno de los resultados conduce a una biblioteca no gratuita que puede ser útil ( Chilkat Http)

Si escribes tu propio marco de comandos HTTP en la parte superior de .Net, creo que todos podemos disfrutarlo si lo compartes :-)

Otros consejos

Si está utilizando .NET 4.5 use esto:

public string Upload(string url, NameValueCollection requestParameters, MemoryStream file)
        {

            var client = new HttpClient();
            var content = new MultipartFormDataContent();

            content.Add(new StreamContent(file));
            System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>> b = new List<KeyValuePair<string, string>>();
            b.Add(requestParameters);
            var addMe = new FormUrlEncodedContent(b);

            content.Add(addMe);
            var result = client.PostAsync(url, content);
            return result.Result.ToString();
        }

De lo contrario, según la respuesta de Ryan, descargué la biblioteca y la modifiqué un poco.

  public class MimePart
        {
            NameValueCollection _headers = new NameValueCollection();
            byte[] _header;

            public NameValueCollection Headers
            {
                get { return _headers; }
            }

            public byte[] Header
            {
                get { return _header; }
            }

            public long GenerateHeaderFooterData(string boundary)
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("--");
                sb.Append(boundary);
                sb.AppendLine();
                foreach (string key in _headers.AllKeys)
                {
                    sb.Append(key);
                    sb.Append(": ");
                    sb.AppendLine(_headers[key]);
                }
                sb.AppendLine();

                _header = Encoding.UTF8.GetBytes(sb.ToString());

                return _header.Length + Data.Length + 2;
            }

            public Stream Data { get; set; }
        }

        public string Upload(string url, NameValueCollection requestParameters, params MemoryStream[] files)
        {
            using (WebClient req = new WebClient())
            {
                List<MimePart> mimeParts = new List<MimePart>();

                try
                {
                    foreach (string key in requestParameters.AllKeys)
                    {
                        MimePart part = new MimePart();

                        part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
                        part.Data = new MemoryStream(Encoding.UTF8.GetBytes(requestParameters[key]));

                        mimeParts.Add(part);
                    }

                    int nameIndex = 0;

                    foreach (MemoryStream file in files)
                    {
                        MimePart part = new MimePart();
                        string fieldName = "file" + nameIndex++;

                        part.Headers["Content-Disposition"] = "form-data; name=\"" + fieldName + "\"; filename=\"" + fieldName + "\"";
                        part.Headers["Content-Type"] = "application/octet-stream";

                        part.Data = file;

                        mimeParts.Add(part);
                    }

                    string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
                    req.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);

                    long contentLength = 0;

                    byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");

                    foreach (MimePart part in mimeParts)
                    {
                        contentLength += part.GenerateHeaderFooterData(boundary);
                    }

                    //req.ContentLength = contentLength + _footer.Length;

                    byte[] buffer = new byte[8192];
                    byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
                    int read;

                    using (MemoryStream s = new MemoryStream())
                    {
                        foreach (MimePart part in mimeParts)
                        {
                            s.Write(part.Header, 0, part.Header.Length);

                            while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
                                s.Write(buffer, 0, read);

                            part.Data.Dispose();

                            s.Write(afterFile, 0, afterFile.Length);
                        }

                        s.Write(_footer, 0, _footer.Length);
                        byte[] responseBytes = req.UploadData(url, s.ToArray());
                        string responseString = Encoding.UTF8.GetString(responseBytes);
                        return responseString;
                    }
                }
                catch
                {
                    foreach (MimePart part in mimeParts)
                        if (part.Data != null)
                            part.Data.Dispose();

                    throw;
                }
            }
        }

No lo he intentado yo mismo, pero parece haber una forma integrada en C # para esto (aunque aparentemente no es muy conocido ...):

private static HttpClient _client = null;

private static void UploadDocument()
{
    // Add test file 
    var httpContent = new MultipartFormDataContent();
    var fileContent = new ByteArrayContent(File.ReadAllBytes(@"File.jpg"));
    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = "File.jpg"
    };

    httpContent.Add(fileContent);
    string requestEndpoint = "api/Post";

    var response = _client.PostAsync(requestEndpoint, httpContent).Result;

    if (response.IsSuccessStatusCode)
    {
        // ...
    }
    else
    {
        // Check response.StatusCode, response.ReasonPhrase
    }
}

Pruébalo y hazme saber cómo va.

¡Salud!

He tenido éxito con el código publicado en aspnetupload .com . Terminé haciendo mi propia versión de su biblioteca UploadHelper que es compatible con Compact Framework. Funciona bien, parece hacer exactamente lo que necesita.

La clase System.Net.WebClient puede ser lo que está buscando. Consulte la documentación de WebClient.UploadFile, debería permitirle cargar un archivo a un recurso específico a través de una de las sobrecargas de UploadFile. Creo que este es el método que desea utilizar para publicar los datos ...

Se puede usar como ... tenga en cuenta que esto es solo un código de ejemplo no probado ...

WebClient webClient = new WebClient ();

webClient.UploadFile (" http://www.url.com/ReceiveUploadedFile.aspx " ;, " POST " ;, @ " c: \ myfile.txt ");

Aquí está la referencia de MSDN si está interesado.

http://msdn.microsoft.com /en-us/library/system.net.webclient.uploadfile.aspx

Espero que esto ayude.

Normalmente, Fiddler es la mejor herramienta para ese trabajo. Muy fácil de crear solicitudes e incluso genera algunos de los encabezados para ti.

Fiddler - Cómo crear una solicitud

ingrese la descripción de la imagen aquí

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top