2013-05-07 19 views
73

Qualcuno sa come utilizzare lo HttpClient in .Net 4.5 con il caricamento multipart/form-data?C# HttpClient 4.5 upload multipart/form-data

Non sono riuscito a trovare alcun esempio su Internet.

+1

Ho provato ma non ho idea di come avviarlo .. dove aggiungo il byteArray al contenuto e così via. ho bisogno di un aiuto per iniziare. – ident

risposta

89

il mio risultato è simile al seguente:

public static async Task<string> Upload(byte[] image) 
{ 
    using (var client = new HttpClient()) 
    { 
     using (var content = 
      new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture))) 
     { 
      content.Add(new StreamContent(new MemoryStream(image)), "bilddatei", "upload.jpg"); 

       using (
       var message = 
        await client.PostAsync("http://www.directupload.net/index.php?mode=upload", content)) 
       { 
        var input = await message.Content.ReadAsStringAsync(); 

        return !string.IsNullOrWhiteSpace(input) ? Regex.Match(input, @"http://\w*\.directupload\.net/images/\d*/\w*\.[a-z]{3}").Value : null; 
       } 
      } 
    } 
} 
+2

Wow, è molto più semplice farlo quando si caricano file di grandi dimensioni sull'API REST. Non mi piace commentare per grazie, ma grazie. È portatile per Windows Phone 8. –

+19

Attenzione, 'HttpClient' deve essere riutilizzato il più possibile all'interno dell'applicazione. Racchiuderlo con una frase 'using' è considerato una cattiva pratica. Questo è stato documentato su molti blog post e libri. Ecco la mia lettura preferita sull'argomento: http://chimera.labs.oreilly.com/books/1234000001708/ch14.html –

+1

Questo codice non è riuscito per me poiché la stringa di limite passata a 'new MultipartFormDataContent (...)' contenuta un carattere di limite non valido (forse il separatore "/"). Nessun errore, solo nessun file inserito nel server - nel mio caso, Context.Request.Files.Count = 0 nel controller API. Forse solo un problema di 'Nancy', ma suggerisco di usare qualcosa come' DateTime.Now.Ticks.ToString ("x") 'invece. – Dunc

56

funziona in modo più o meno così (ad esempio utilizzando un file/jpg immagine):

async public Task<HttpResponseMessage> UploadImage(string url, byte[] ImageData) 
{ 
    var requestContent = new MultipartFormDataContent(); 
    // here you can specify boundary if you need---^ 
    var imageContent = new ByteArrayContent(ImageData); 
    imageContent.Headers.ContentType = 
     MediaTypeHeaderValue.Parse("image/jpeg"); 

    requestContent.Add(imageContent, "image", "image.jpg"); 

    return await client.PostAsync(url, requestContent); 
} 

(È possibile requestContent.Add() quello che volete, date un'occhiata al HttpContent descendant per vedere tipi disponibili a passare in)

Al termine, è possibile trovare il contenuto della risposta all'interno di HttpResponseMessage.Content che è possibile consumare con HttpContent.ReadAs*Async.

+0

grazie, ho risolto questo problema una settimana prima del tuo post, ma grazie comunque .. – ident

+0

why image.jpg ?? – Toolkit

+1

Ahhh grazie per il '// qui puoi specificare il limite se ti serve --- ^' :) – sfarbota

32

Questo è un esempio di come inviare stringa e file di flusso con HTTPClient utilizzando MultipartFormDataContent. La Content-Disposition e Content-Type devono essere specificati per ogni HTTPContent:

Ecco il mio esempio. Spero che sia d'aiuto:

private static void Upload() 
{ 
    using (var client = new HttpClient()) 
    { 
     client.DefaultRequestHeaders.Add("User-Agent", "CBS Brightcove API Service"); 

     using (var content = new MultipartFormDataContent()) 
     { 
      var path = @"C:\B2BAssetRoot\files\596086\596086.1.mp4"; 

      string assetName = Path.GetFileName(path); 

      var request = new HTTPBrightCoveRequest() 
       { 
        Method = "create_video", 
        Parameters = new Params() 
         { 
          CreateMultipleRenditions = "true", 
          EncodeTo = EncodeTo.Mp4.ToString().ToUpper(), 
          Token = "x8sLalfXacgn-4CzhTBm7uaCxVAPjvKqTf1oXpwLVYYoCkejZUsYtg..", 
          Video = new Video() 
           { 
            Name = assetName, 
            ReferenceId = Guid.NewGuid().ToString(), 
            ShortDescription = assetName 
           } 
         } 
       }; 

      //Content-Disposition: form-data; name="json" 
      var stringContent = new StringContent(JsonConvert.SerializeObject(request)); 
      stringContent.Headers.Add("Content-Disposition", "form-data; name=\"json\""); 
      content.Add(stringContent, "json"); 

      FileStream fs = File.OpenRead(path); 

      var streamContent = new StreamContent(fs); 
      streamContent.Headers.Add("Content-Type", "application/octet-stream"); 
      //Content-Disposition: form-data; name="file"; filename="C:\B2BAssetRoot\files\596090\596090.1.mp4"; 
      streamContent.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"" + Path.GetFileName(path) + "\""); 
      content.Add(streamContent, "file", Path.GetFileName(path)); 

      //content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 

      Task<HttpResponseMessage> message = client.PostAsync("http://api.brightcove.com/services/post", content); 

      var input = message.Result.Content.ReadAsStringAsync(); 
      Console.WriteLine(input.Result); 
      Console.Read(); 
     } 
    } 
} 
+6

@Trout Non hai idea di come il tuo codice mi abbia reso così felice oggi! +1 – Pinch

+4

Questa è la risposta completa. –

+1

So che non dovremmo commentare una nota di ringraziamento. Ma questo qui è il miglior codice che ho visto su come usare 'MultipartFormDataContent'.Complimenti a voi signore – sebagomez

5

Ecco un esempio completo che ha funzionato per me. Il valore boundary nella richiesta viene aggiunto automaticamente da .NET.

var url = "http://localhost/api/v1/yourendpointhere"; 
var filePath = @"C:\path\to\image.jpg"; 

HttpClient httpClient = new HttpClient(); 
MultipartFormDataContent form = new MultipartFormDataContent(); 

FileStream fs = File.OpenRead(filePath); 
var streamContent = new StreamContent(fs); 

var imageContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result); 
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); 

form.Add(imageContent, "image", Path.GetFileName(filePath)); 
var response = httpClient.PostAsync(url, form).Result; 
+0

Come possiamo inviare un token con questo? Vedi questo per favore: https://stackoverflow.com/questions/48295877/webclient-too-many-automatic-redirections-were-attempted –