С# HttpClient 4.5 multipart/form-data upload

Кто-нибудь знает, как использовать HttpClient в .Net 4.5 с загрузкой multipart/form-data?

Я не мог найти примеров в Интернете.

Ответ 1

мой результат выглядит следующим образом:

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

Это работает примерно так (пример с использованием файла image/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, чтобы просмотреть доступные типы)

По завершении вы найдете контент ответа внутри HttpResponseMessage.Content, который вы можете использовать с помощью HttpContent.ReadAs*Async.

Ответ 3

Это пример того, как отправлять поток строк и файлов с помощью HTTPClient с помощью MultipartFormDataContent. Для каждого HTTPContent необходимо указать Content-Disposition и Content-Type:

Вот мой пример. Надеюсь, это поможет:

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

Ответ 4

Вот еще один пример того, как использовать HttpClient для загрузки multipart/form-data.

Он загружает файл в API REST и включает в себя сам файл (например, JPG) и дополнительные параметры API. Файл напрямую загружается с локального диска через FileStream.

Смотрите здесь для полного примера, включая дополнительную логику, специфичную для API.

public static async Task UploadFileAsync(string token, string path, string channels)
{
    // we need to send a request with multipart/form-data
    var multiForm = new MultipartFormDataContent();

    // add API method parameters
    multiForm.Add(new StringContent(token), "token");
    multiForm.Add(new StringContent(channels), "channels");

    // add file and directly upload it
    FileStream fs = File.OpenRead(path);
    multiForm.Add(new StreamContent(fs), "file", Path.GetFileName(path));

    // send request to API
    var url = "https://slack.com/api/files.upload";
    var response = await client.PostAsync(url, multiForm);
}

Ответ 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;

Ответ 6

Попробуйте, это работает для меня.

private static async Task<object> Upload(string actionUrl)
{
    Image newImage = Image.FromFile(@"Absolute Path of image");
        ImageConverter _imageConverter = new ImageConverter();
        byte[] paramFileStream= (byte[])_imageConverter.ConvertTo(newImage, typeof(byte[]));

    var formContent = new MultipartFormDataContent
    {
    //send form text values here
         {new StringContent("value1"),"key1"},
         {new StringContent("value2"),"key2" },
    // send Image Here
         {new StreamContent(new MemoryStream(paramFileStream)),"imagekey","filename.jpg"}
    };

    var myHttpClient = new HttpClient();
    var response = await myHttpClient.PostAsync(actionUrl.ToString(), formContent);
    string stringContent = await response.Content.ReadAsStringAsync();

    return response;
}

Ответ 7

        X509Certificate clientKey1 = null;
        clientKey1 = new X509Certificate(AppSetting["certificatePath"],  
        AppSetting["pswd"]);
        string url = "Https://EndPointAddress";
        FileStream fs = File.OpenRead(FilePath);
        var streamContent = new StreamContent(fs);

        var FileContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);            
        FileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("ContentType");
        var handler = new WebRequestHandler();       


            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.ClientCertificates.Add(clientKey1);
            handler.ServerCertificateValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) =>
            {
                return true;
            };            


        using (var client = new HttpClient(handler))
        {
            // post it
            HttpResponseMessage httpResponseMessage = client.PostAsync(url, FileContent).Result;
            if (!httpResponseMessage.IsSuccessStatusCode)
            {

                string ss = httpResponseMessage.StatusCode.ToString();
            }
        }   

Ответ 8

Я добавляю фрагмент кода, который показывает, как отправить файл в API, который был открыт через команду DELETE http. Это не распространенный случай загрузки файла с помощью команды DELETE http, но это разрешено. Я принял аутентификацию Windows NTLM для авторизации вызова.

Проблема, с которой можно столкнуться, состоит в том, что все перегрузки метода HttpClient.DeleteAsync не имеют параметров для HttpContent, как мы получаем его в методе PostAsync

var requestUri = new Uri("http://UrlOfTheApi");
using (var streamToPost = new MemoryStream("C:\temp.txt"))
using (var fileStreamContent = new StreamContent(streamToPost))
using (var httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true })
using (var httpClient = new HttpClient(httpClientHandler, true))
using(var requestMessage = new HttpRequestMessage(HttpMethod.Delete, requestUri))
using (var formDataContent = new MultipartFormDataContent())
{
       formDataContent.Add(fileStreamContent, "myFile", "temp.txt");
       requestMessage.Content = formDataContent;
       var response = httpClient.SendAsync(requestMessage).GetAwaiter().GetResult();
       if (response.IsSuccessStatusCode)
       {
             //file upload was successfull
       }
       else
       {
             var erroResult = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
             throw new Exception("Error on the server : " + erroResult);
        }
}

Вам нужны ниже пространства имен в верхней части файла С#:

using System;
using System.Net;
using System.IO;
using System.Net.Http;

P.S. Извините за очень много использования блоков (шаблон IDisposable) в моем коде. К сожалению, синтаксис использования конструкции С# не поддерживает инициализацию нескольких переменных в одном операторе.

Ответ 9

public async Task<object> PassImageWithText(IFormFile files)
{
  byte[] data;
  string result = "";
  ByteArrayContent bytes;

  MultipartFormDataContent multiForm = 
    new MultipartFormDataContent();
    try
    {
        using (var client = new HttpClient())
        {
            using (var br = new BinaryReader(files.OpenReadStream()))
                data = br.ReadBytes((int)files.OpenReadStream().Length);

            bytes = new ByteArrayContent(data);
            multiForm.Add(bytes, "files", files.FileName);
            multiForm.Add(new StringContent("value1"), "key1");
            multiForm.Add(new StringContent("value2"), "key2");

            var res = await client.PostAsync(_MEDIA_ADD_IMG_URL, multiForm);

        }
    }
    catch (Exception e)
    {
        throw new Exception(e.ToString());
    }
    return result;
}