2009-07-30 98 views
14

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

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

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

+1

He estado buscando principalmente en HttpWebRequest, pero cada recurso que he encontrado en Internet explica cómo crear manualmente la solicitud. Este es uno de los muchos ejemplos similares que he encontrado: http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/03efc98c-68e2-410c-bf25-d5facacbd920 –

+0

Esta pregunta tiene una respuesta que resuelve su problema al publicar multipart/form-data usando WebRequest. Funciona bien. http://stackoverflow.com/questions/219827/multipart-forms-from-c-client – Marek

Respuesta

1

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

En segundo lugar, creo que puede intentar buscar una implementación de navegador en .Net. Vi this one, tal vez cubre el problema sobre el que preguntaste. O simplemente puede buscar "C# http put get post request". Uno de los resultados conduce a una biblioteca no libre que puede ser útil (Chilkat Http)

Si escribe su propio marco de comandos HTTP encima de .Net, creo que todos podemos disfrutarlo si comparte it :-)

+0

Lamentablemente, esto es lo que tenía que hacer. –

1

La clase System.Net.WebClient puede ser lo que estás 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 busca utilizar para publicar los datos ...

Puede ser utilizado como .... en cuenta que este es código sólo muestra 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.

+1

Eso funcionaría si solo subiera el archivo. Sin embargo, necesito incluir un montón de otras variables de formulario junto con él. –

2

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

+0

Debo añadir que "hacer mi propia versión" == intentar compilar la biblioteca en un proyecto de Framework compacto, ver qué está roto, usar otro objeto compatible con CF o segmento de código para hacer lo mismo, repetir. Me sorprendió gratamente lo simple que fue ese proceso. –

5

Si está utilizando .NET 4.5 uso 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 Sobre la base de la respuesta de Ryan, he descargado la biblioteca y ajustado 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; 
       } 
      } 
     } 
+1

La primera función no funciona. ¿Qué es "a"? – user656822

+0

Vaya, debería haber sido requestParameters. Fijo. –

+0

Sé que es viejo, pero no funcionó para mí hasta que cité mi contenido manualmente como se ve aquí -> http://stackoverflow.com/a/12034014/885338 – Arikael

-1

Normalmente encuentro Fiddler para ser la mejor herramienta para ese trabajo. Muy fácil de crear solicitudes e incluso genera algunos de los encabezados para usted.

Fiddler - How to create a request

enter image description here

2

No he probado esto por mí mismo, pero parece que hay una manera integrada en C# para esto (aunque no muy conocido, aparentemente ...):

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 cuéntame cómo te va.

¡Salud!

Cuestiones relacionadas