2012-08-15 13 views
5

Sto cercando di fare un post come questo:Perché il POST genera un'eccezione in 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(); 
    }); 

ma ricevo questa eccezione:

URI non valido: La stringa di Uri è troppo lunga.

lamentarsi di questa riga: HttpContent content = new FormUrlEncodedContent(postData);. Per i file di piccole dimensioni funziona, ma non capisco perché per quelli più grandi non lo fa?

Quando faccio il POST il contenuto può essere più grande ... Allora perché si lamenta dell'URI?

risposta

4

È necessario utilizzare MultipartFormDataContent (http://msdn.microsoft.com/en-us/library/system.net.http.multipartformdatacontent%28v=vs.110%29) anziché FormUrlEncodedContent, che invia i dati come "application/x-www-form-urlencoded".

Quindi, anche se si utilizza il verbo POST, è ancora il POST a un URL molto lungo contenente i dati, quindi l'errore.

Il tipo di contenuto "/ x-www-form-urlencoded applicazione" è inefficiente per l'invio di grandi quantità di dati binari o di testo contenente caratteri non-ASCII. Il tipo di contenuto "multipart/form-data" deve essere utilizzato per l'invio di moduli che contengono file, dati non ASCII e dati binari .

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

Per un campione, uno sguardo a questa risposta: ASP.NET WebApi: how to perform a multipart post with file upload using WebApi HttpClient

+0

Grazie! Hai qualche esempio come farlo? È corretto? 'MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent(); multipartFormDataContent.Add (nuovo FormUrlEncodedContent (postData)); ' –

+0

@CristianBoariu Aggiornato la mia risposta per collegare un campione – mathieu

+1

@mathieu che l'esempio lancia ancora l'Eccezione, poiché FormUrlEncodedContent è compilato –

0

So che questo è già stato risposto, ma mi sono imbattuto in questo stesso problema e ha scoperto che è un limitazione nella classe FormUrlEncodedContent. Il motivo dell'errore è che la codifica degli oggetti viene gestita dallo Uri.EscapeDataString(). This post explains it on CodePlex. Alla fine ho trovato la mia soluzione per Url Encode usando invece la classe HTTPUtility.

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); 
     } 
    } 


} 

ho scritto un piccolo article su come ho implementato esso. Spero che questo aiuti chiunque abbia gli stessi problemi.