Вопрос

Какой самый простой способ отправить HTTP POST-запрос с типом содержимого multipart / form-data из C #?Должен быть способ получше, чем создать мой собственный запрос.

Причина, по которой я прошу, - загрузить фотографии на Flickr с помощью этого api:

http://www.flickr.com/services/api/upload.api.html

Это было полезно?

Решение

Во-первых, нет ничего плохого в чисто ручной реализации HTTP-команд с использованием .Net framework. Имейте в виду, что это фреймворк, и он должен быть довольно общим.

Во-вторых, я думаю, вы можете попробовать поискать реализацию браузера в .Net. Я видел этот , возможно, он охватывает проблему, которую вы задали около. Или вы можете просто найти " C # http поставить запрос получения поста " ;. Один из результатов приводит к несвободной библиотеке, которая может оказаться полезной ( Chilkat Http)

Если вам случится написать свой собственный каркас HTTP-команд поверх .Net - я думаю, что нам всем это понравится, если вы поделитесь им: -)

Другие советы

Если вы используете .NET 4.5, используйте это:

public string Upload(string url, NameValueCollection requestParameters, MemoryStream file)
        {

            var client = new HttpClient();
            var content = new MultipartFormDataContent();

            content.Add(new StreamContent(file));
            System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>> b = new List<KeyValuePair<string, string>>();
            b.Add(requestParameters);
            var addMe = new FormUrlEncodedContent(b);

            content.Add(addMe);
            var result = client.PostAsync(url, content);
            return result.Result.ToString();
        }

В противном случае, основываясь на ответе Райана, я скачал библиотеку и немного подправил ее.

  public class MimePart
        {
            NameValueCollection _headers = new NameValueCollection();
            byte[] _header;

            public NameValueCollection Headers
            {
                get { return _headers; }
            }

            public byte[] Header
            {
                get { return _header; }
            }

            public long GenerateHeaderFooterData(string boundary)
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("--");
                sb.Append(boundary);
                sb.AppendLine();
                foreach (string key in _headers.AllKeys)
                {
                    sb.Append(key);
                    sb.Append(": ");
                    sb.AppendLine(_headers[key]);
                }
                sb.AppendLine();

                _header = Encoding.UTF8.GetBytes(sb.ToString());

                return _header.Length + Data.Length + 2;
            }

            public Stream Data { get; set; }
        }

        public string Upload(string url, NameValueCollection requestParameters, params MemoryStream[] files)
        {
            using (WebClient req = new WebClient())
            {
                List<MimePart> mimeParts = new List<MimePart>();

                try
                {
                    foreach (string key in requestParameters.AllKeys)
                    {
                        MimePart part = new MimePart();

                        part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
                        part.Data = new MemoryStream(Encoding.UTF8.GetBytes(requestParameters[key]));

                        mimeParts.Add(part);
                    }

                    int nameIndex = 0;

                    foreach (MemoryStream file in files)
                    {
                        MimePart part = new MimePart();
                        string fieldName = "file" + nameIndex++;

                        part.Headers["Content-Disposition"] = "form-data; name=\"" + fieldName + "\"; filename=\"" + fieldName + "\"";
                        part.Headers["Content-Type"] = "application/octet-stream";

                        part.Data = file;

                        mimeParts.Add(part);
                    }

                    string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
                    req.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);

                    long contentLength = 0;

                    byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");

                    foreach (MimePart part in mimeParts)
                    {
                        contentLength += part.GenerateHeaderFooterData(boundary);
                    }

                    //req.ContentLength = contentLength + _footer.Length;

                    byte[] buffer = new byte[8192];
                    byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
                    int read;

                    using (MemoryStream s = new MemoryStream())
                    {
                        foreach (MimePart part in mimeParts)
                        {
                            s.Write(part.Header, 0, part.Header.Length);

                            while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
                                s.Write(buffer, 0, read);

                            part.Data.Dispose();

                            s.Write(afterFile, 0, afterFile.Length);
                        }

                        s.Write(_footer, 0, _footer.Length);
                        byte[] responseBytes = req.UploadData(url, s.ToArray());
                        string responseString = Encoding.UTF8.GetString(responseBytes);
                        return responseString;
                    }
                }
                catch
                {
                    foreach (MimePart part in mimeParts)
                        if (part.Data != null)
                            part.Data.Dispose();

                    throw;
                }
            }
        }

Я сам этого не пробовал, но, похоже, в C # есть встроенный способ для этого (хотя, по-видимому, не очень известный ...):

private static HttpClient _client = null;

private static void UploadDocument()
{
    // Add test file 
    var httpContent = new MultipartFormDataContent();
    var fileContent = new ByteArrayContent(File.ReadAllBytes(@"File.jpg"));
    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = "File.jpg"
    };

    httpContent.Add(fileContent);
    string requestEndpoint = "api/Post";

    var response = _client.PostAsync(requestEndpoint, httpContent).Result;

    if (response.IsSuccessStatusCode)
    {
        // ...
    }
    else
    {
        // Check response.StatusCode, response.ReasonPhrase
    }
}

Попробуйте и дайте мне знать, как все пройдет.

Ваше здоровье!

Я успешно справился с кодом, размещенным на aspnetupload .com . Я закончил тем, что сделал свою собственную версию их библиотеки UploadHelper, которая совместима с Compact Framework. Работает хорошо, похоже, делает именно то, что вам нужно.

Класс System.Net.WebClient может быть тем, что вы ищете. Проверьте документацию для WebClient.UploadFile, он должен позволить вам загрузить файл на указанный ресурс через одну из перегрузок UploadFile. Я думаю, что этот метод вы хотите использовать для публикации данных ...

Его можно использовать как .... обратите внимание, это просто пример кода, который не тестировался ...

WebClient webClient = new WebClient ();

webClient.UploadFile (" http://www.url.com/ReceiveUploadedFile.aspx " ;, " POST " ;, @ " c: \ myfile.txt ");

Вот ссылка на MSDN, если вы заинтересованы.

http://msdn.microsoft.com /en-us/library/system.net.webclient.uploadfile.aspx

Надеюсь, это поможет.

Я обычно нахожу Fiddler лучшим инструментом для этой работы. Очень легко создавать запросы, и он даже генерирует некоторые заголовки для вас.

Fiddler - как создать запрос

введите описание изображения здесь

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top