2012-08-15 14 views
5

que estoy tratando de hacer un post como este:¿Por qué hacer POST arroja una excepción en MVC 4?

HttpClient hc = new HttpClient(); 
    byte[] bytes = ReadFile(@"my_path"); 

    var postData = new List<KeyValuePair<string, string>>(); 
    postData.Add(new KeyValuePair<string, string>("FileName", "001.jpeg")); 
    postData.Add(new KeyValuePair<string, string>("ConvertToExtension", ".pdf")); 
    postData.Add(new KeyValuePair<string, string>("Content", Convert.ToBase64String(bytes))); 

    HttpContent content = new FormUrlEncodedContent(postData); 
    hc.PostAsync("url", content).ContinueWith((postTask) => { 
    postTask.Result.EnsureSuccessStatusCode(); 
    }); 

pero recibo esta excepción:

URI no válido: La cadena de Uri es demasiado largo.

quejándose de esta línea: HttpContent content = new FormUrlEncodedContent(postData);. Para archivos pequeños, funciona, pero no entiendo por qué para los más grandes no funciona.

Cuando lo hago POST el contenido puede ser más grande ... Entonces, ¿por qué se queja de URI?

Respuesta

4

Debe usar MultipartFormDataContent (http://msdn.microsoft.com/en-us/library/system.net.http.multipartformdatacontent%28v=vs.110%29) en lugar de FormUrlEncodedContent, que envía sus datos como "application/x-www-form-urlencoded".

Así que incluso si está usando el verbo POST, aún está PUBLICANDO una url muy larga que contiene sus datos, de ahí el error.

El tipo de contenido "application/x-www-form-urlencoded" es ineficiente para el envío de grandes cantidades de datos binarios o de texto que contienen caracteres no ASCII. El tipo de contenido "multipart/form-data" debe ser utilizado para enviar formularios que contienen archivos, datos no ASCII y datos binarios.

Ver: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1

Para una muestra, echar un vistazo a esta respuesta: ASP.NET WebApi: how to perform a multipart post with file upload using WebApi HttpClient

+0

Gracias! ¿Tienes algún ejemplo de cómo hacer esto? ¿Es esto correcto? 'MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent(); multipartFormDataContent.Add (new FormUrlEncodedContent (postData)); ' –

+0

@CristianBoariu Actualizado mi respuesta para vincular una muestra – mathieu

+1

@mathieu ese ejemplo todavía arroja la excepción, ya que el FormUrlEncodedContent es compilación –

0

Sé que esto ya ha sido contestada, pero me encontré con este mismo tema y encontraron que es una limitación en la clase FormUrlEncodedContent. El motivo del error es que la codificación de los objetos está siendo manejada por el Uri.EscapeDataString(). This post explains it on CodePlex. Terminé creando mi propia solución para Url Encode usando la clase HTTPUtility en su lugar.

using System.Collections.Generic; 
using System.Linq; 
using System.Net.Http; 
using System.Text; 
using System.Web; 

namespace Wfm.Net.Http 
{ 
    public class UrlContent : ByteArrayContent 
    { 
     public UrlContent(IEnumerable<KeyValuePair<string, string>> content) 
      : base(GetCollectionBytes(content, Encoding.UTF8)) 
     { 
     } 

     public UrlContent(byte[] content, int offset, int count) : base(content, offset, count) 
     { 
     } 

     private static byte[] GetCollectionBytes(IEnumerable<KeyValuePair<string, string>> c, Encoding encoding) 
     { 
      string str = string.Join("&", c.Select(i => string.Concat(HttpUtility.UrlEncode(i.Key), '=', HttpUtility.UrlEncode(i.Value))).ToArray()); 
      return encoding.GetBytes(str); 
     } 
    } 


} 

escribí un pequeño article de cómo he implementado él. Espero que esto ayude a cualquiera con los mismos problemas.

Cuestiones relacionadas