2013-05-07 3 views
73

誰もがmultipart/form-dataで.Net 4.5のHttpClientを使用する方法を知っていますか?C#HttpClient 4.5 multipart/form-data upload

インターネットで例が見つかりませんでした。

+1

私は試してみましたが、私はそれをどのように起動するのかはわかりませんでした。ここで私はコンテンツにbyteArrayを追加します。私はちょっとしたスタートヘルプが必要です。 – ident

答えて

89

私の結果は次のようになります。

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

うわー、大きなファイルをREST APIにアップロードするときにこれを行う方がずっと簡単です。私は感謝のためにコメントしたくないが、感謝している。 Windows Phone 8の移植性があります。 –

+19

「HttpClient」は、アプリケーション内でできるだけ再利用されることを前提としています。 'using'ステートメントでそれを折り返すことは悪い習慣とみなされます。これは多くのブログの投稿や書籍に記載されています。ここに私のお気に入りの読書があります:http://chimera.labs.oreilly.com/books/1234000001708/ch14.html –

+1

このコードは、 'new MultipartFormDataContent(...)'に渡された境界文字列として含まれていませんでした。無効な境界文字(多分 "/"セパレータ)。エラーはありません。サーバに投稿されたファイルはありません。私の場合は 、APIコントローラではContext.Request.Files.Count = 0です。おそらく単にナンシーの問題ですが、代わりに 'DateTime.Now.Ticks.ToString(" x ")'のようなものを使うことをお勧めします。 – Dunc

56

それは多かれ少なかれ(画像/ JPGファイルを使用した例)次のように動作します。

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

(あなたがrequestContent.Add()何でもしたい、で渡すために利用可能なタイプを見てHttpContent descendantで見てみることができます)

完了すると、HttpContent.ReadAs*Asyncで消費できる応答内容がHttpResponseMessage.Contentにあります。

+0

ありがとう、私はあなたのポストの前にこの問題を解決しましたが、とにかくあなたに感謝.. – ident

+0

なぜimage.jpg ?? – Toolkit

+1

Ahhhは 'のために感謝します//ここであなたが必要なら境界を指定できます^' :) – sfarbota

32

これは、HTTPClientのはMultipartFormDataContentを使用して文字列とファイルストリームを投稿する方法の例です。 Content-DispositionとContent-TypeをHTTPContentごとに指定する必要があります。

これは私の例です。希望する:

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あなたのコードが今日私がどのようにして幸せになったのか分かりません! +1 – Pinch

+4

これは完全な答えです。 –

+1

私はあなたに感謝の意を表することはできません。しかし、ここでこれは 'MultipartFormDataContent'の使い方について私が見てきた最良のコードです。あなたへの名誉 – sebagomez

5

私のために働いた完全なサンプルがあります。要求のboundaryの値は.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

これでどのようにトークンを送信できますか?こちらをご覧ください:https://stackoverflow.com/questions/48295877/webclient-too-many-automatic-redirections-were-attempted –