2013-05-07 8 views
73

Weiß jemand, wie man die HttpClient in .Net 4.5 mit multipart/form-data Upload verwendet?C# HttpClient 4.5 multipart/Formular-Daten-Upload

Ich konnte keine Beispiele im Internet finden.

+1

Ich habe versucht, aber ich habe keine Ahnung, wie ich es starten .. wo ich das ByteArray zum Inhalt hinzufügen und so weiter. Ich brauche eine Art Starthilfe. – ident

Antwort

89

mein Ergebnis sieht wie folgt aus:

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, es ist so viel einfacher, dies beim Hochladen großer Dateien in REST API zu tun. Ich möchte nicht für den Dank kommentieren, aber danke. Es ist portabel für Windows Phone 8. –

+19

Beachten Sie, 'HttpClient' soll so weit wie möglich in Ihrer Anwendung wiederverwendet werden. Es mit einer 'using'-Anweisung zu verpacken, wird als schlechte Praxis angesehen. Dies wurde in vielen Blogposts und Büchern dokumentiert. Hier ist meine Lieblingslesung zu diesem Thema: http://chimera.labs.oreilly.com/books/1234000001708/ch14.html –

+1

Dieser Code ist fehlgeschlagen für mich, da die Grenzzeichenfolge an 'new MultipartFormDataContent (...) 'enthalten ist ein ungültiges Begrenzungszeichen (möglicherweise das Trennzeichen "/"). Keine Fehler, nur keine Dateien auf dem Server - in meinem Fall Context.Request.Files.Count = 0 im API-Controller. Möglicherweise nur ein 'Nancy'-Problem, aber ich schlage stattdessen etwas wie 'DateTime.Now.Ticks.ToString (" x ")' vor. – Dunc

56

Es funktioniert mehr oder weniger wie folgt aus (zB ein Bild/jpg-Datei):

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

(Sie können requestContent.Add(), was Sie wollen, am HttpContent descendant einen Blick verfügbaren Typen zu sehen, passieren in)

Wenn Sie fertig sind, finden Sie den Antwortinhalt in HttpResponseMessage.Content, den Sie mit HttpContent.ReadAs*Async konsumieren können.

+0

danke, ich löste dieses Problem eine Woche vor Ihrem Post, aber danke trotzdem .. – ident

+0

warum image.jpg ?? – Toolkit

+1

Ahhh danke für das '// hier können Sie Grenze angeben, wenn Sie brauchen --- ^' :) – sfarbota

32

Dies ist ein Beispiel dafür, wie String und Datei-Stream schreiben mit Httpclient MultipartFormDataContent verwenden. Die Content-Disposition und Content-Type müssen für jeden HTTPContent angegeben werden:

Hier ist mein Beispiel. Hoffe es hilft:

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 Sie haben keine Ahnung, wie Ihr Code mich heute so glücklich gemacht hat! +1 – Pinch

+4

Dies ist die vollständige Antwort. –

+1

Ich weiß, wir sollen nicht eine Dankesnote kommentieren. Aber das hier ist der beste Code, den ich gesehen habe, wie man 'MultipartFormDataContent' benutzt.Kudos an Sie Herr – sebagomez

5

Hier ist eine vollständige Probe, die für mich arbeitete. Der Wert boundary in der Anfrage wird automatisch von .NET hinzugefügt.

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

Wie können wir damit ein Token senden? Siehe bitte: https://stackoverflow.com/questions/48295877/webclient-too-many-automatic-redirections-wurden versucht –