Как сделать HTTP-запрос HTTP POST

  Канонический
Как я могу сделать HTTP-запрос и отправить некоторые данные, используя метод POST ?

Я могу сделать запрос GET, но не знаю, как сделать POST.

Ответ 1

Есть несколько способов выполнить запросы HTTP GET и POST:


Метод A: HttpClient (предпочтительный)

Это обертка вокруг HttpWebRequest. Сравните с WebClient.

Доступно в: .NET Framework 4.5+, .NET Standard 1.1+, .NET Core 1.0+.

В настоящее время предпочтительный подход. Асинхронный. Портативная версия для других платформ доступна через NuGet.

using System.Net.Http;

Setup

Setup Рекомендуется создать экземпляр HttpClient на весь срок службы вашего приложения и поделиться им.

private static readonly HttpClient client = new HttpClient();

Смотрите HttpClientFactory, чтобы найти решение для внедрения зависимостей.


  • POST

    var values = new Dictionary<string, string>
    {
    { "thing1", "hello" },
    { "thing2", "world" }
    };
    
    var content = new FormUrlEncodedContent(values);
    
    var response = await client.PostAsync("http://www.example.com/recepticle.aspx", content);
    
    var responseString = await response.Content.ReadAsStringAsync();
    
  • GET

    var responseString = await client.GetStringAsync("http://www.example.com/recepticle.aspx");
    

Метод B: сторонние библиотеки

  • RestSharp

    Испытанная и протестированная библиотека для взаимодействия с REST API. Портативный. Доступно через NuGet.

  • Flurl.Http

    Более новая библиотека со свободным API и помощниками в тестировании. HttpClient под капотом. Портативный. Доступно через NuGet.

    using Flurl.Http;
    

  • POST

    var responseString = await "http://www.example.com/recepticle.aspx"
        .PostUrlEncodedAsync(new { thing1 = "hello", thing2 = "world" })
        .ReceiveString();
    
  • GET

    var responseString = await "http://www.example.com/recepticle.aspx"
        .GetStringAsync();
    

Метод C: HttpWebRequest (не рекомендуется для новой работы)

Доступно в: .NET Framework 1.1+, .NET Standard 2.0+, .NET Core 1.0+

using System.Net;
using System.Text;  // for class Encoding
using System.IO;    // for StreamReader

  • POST

    var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx");
    
    var postData = "thing1=" + Uri.EscapeDataString("hello");
        postData += "&thing2=" + Uri.EscapeDataString("world");
    var data = Encoding.ASCII.GetBytes(postData);
    
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = data.Length;
    
    using (var stream = request.GetRequestStream())
    {
        stream.Write(data, 0, data.Length);
    }
    
    var response = (HttpWebResponse)request.GetResponse();
    
    var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
    
  • GET

    var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx");
    
    var response = (HttpWebResponse)request.GetResponse();
    
    var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
    

Метод D: WebClient (не рекомендуется для новой работы)

Это обертка вокруг HttpWebRequest. Сравните с HttpClient.

Доступно в: .NET Framework 1.1+, NET Standard 2.0+, .NET Core 2.0+

using System.Net;
using System.Collections.Specialized;

  • POST

    using (var client = new WebClient())
    {
        var values = new NameValueCollection();
        values["thing1"] = "hello";
        values["thing2"] = "world";
    
        var response = client.UploadValues("http://www.example.com/recepticle.aspx", values);
    
        var responseString = Encoding.Default.GetString(response);
    }
    
  • GET

    using (var client = new WebClient())
    {
        var responseString = client.DownloadString("http://www.example.com/recepticle.aspx");
    }
    

Ответ 2

Простой запрос GET

using System.Net;

...

using (var wb = new WebClient())
{
    var response = wb.DownloadString(url);
}

Простой POST-запрос

using System.Net;
using System.Collections.Specialized;

...

using (var wb = new WebClient())
{
    var data = new NameValueCollection();
    data["username"] = "myUser";
    data["password"] = "myPassword";

    var response = wb.UploadValues(url, "POST", data);
    string responseInString = Encoding.UTF8.GetString(response);
}

Ответ 3

У MSDN есть образец.

using System;
using System.IO;
using System.Net;
using System.Text;

namespace Examples.System.Net
{
    public class WebRequestPostExample
    {
        public static void Main()
        {
            // Create a request using a URL that can receive a post. 
            WebRequest request = WebRequest.Create("http://www.contoso.com/PostAccepter.aspx");
            // Set the Method property of the request to POST.
            request.Method = "POST";
            // Create POST data and convert it to a byte array.
            string postData = "This is a test that posts this string to a Web server.";
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            // Set the ContentType property of the WebRequest.
            request.ContentType = "application/x-www-form-urlencoded";
            // Set the ContentLength property of the WebRequest.
            request.ContentLength = byteArray.Length;
            // Get the request stream.
            Stream dataStream = request.GetRequestStream();
            // Write the data to the request stream.
            dataStream.Write(byteArray, 0, byteArray.Length);
            // Close the Stream object.
            dataStream.Close();
            // Get the response.
            WebResponse response = request.GetResponse();
            // Display the status.
            Console.WriteLine(((HttpWebResponse)response).StatusDescription);
            // Get the stream containing content returned by the server.
            dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream);
            // Read the content.
            string responseFromServer = reader.ReadToEnd();
            // Display the content.
            Console.WriteLine(responseFromServer);
            // Clean up the streams.
            reader.Close();
            dataStream.Close();
            response.Close();
        }
    }
}

Ответ 4

Это полный рабочий пример отправки/приема данных в формате JSON, я использовал VS2013 Express Edition

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace ConsoleApplication1
{
    class Customer
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
    }

    public class Program
    {
        private static readonly HttpClient _Client = new HttpClient();
        private static JavaScriptSerializer _Serializer = new JavaScriptSerializer();

        static void Main(string[] args)
        {
            Run().Wait();
        }

        static async Task Run()
        {
            string url = "http://www.example.com/api/Customer";
            Customer cust = new Customer() { Name = "Example Customer", Address = "Some example address", Phone = "Some phone number" };
            var json = _Serializer.Serialize(cust);
            var response = await Request(HttpMethod.Post, url, json, new Dictionary<string, string>());
            string responseText = await response.Content.ReadAsStringAsync();

            List<YourCustomClassModel> serializedResult = _Serializer.Deserialize<List<YourCustomClassModel>>(responseText);

            Console.WriteLine(responseText);
            Console.ReadLine();
        }

        /// <summary>
        /// Makes an async HTTP Request
        /// </summary>
        /// <param name="pMethod">Those methods you know: GET, POST, HEAD, etc...</param>
        /// <param name="pUrl">Very predictable...</param>
        /// <param name="pJsonContent">String data to POST on the server</param>
        /// <param name="pHeaders">If you use some kind of Authorization you should use this</param>
        /// <returns></returns>
        static async Task<HttpResponseMessage> Request(HttpMethod pMethod, string pUrl, string pJsonContent, Dictionary<string, string> pHeaders)
        {
            var httpRequestMessage = new HttpRequestMessage();
            httpRequestMessage.Method = pMethod;
            httpRequestMessage.RequestUri = new Uri(pUrl);
            foreach (var head in pHeaders)
            {
                httpRequestMessage.Headers.Add(head.Key, head.Value);
            }
            switch (pMethod.Method)
            {
                case "POST":
                    HttpContent httpContent = new StringContent(pJsonContent, Encoding.UTF8, "application/json");
                    httpRequestMessage.Content = httpContent;
                    break;

            }

            return await _Client.SendAsync(httpRequestMessage);
        }
    }
}

Ответ 5

Здесь есть несколько действительно хороших ответов. Позвольте мне опубликовать другой способ установки заголовков с помощью WebClient(). Я также покажу вам, как установить ключ API.

        var client = new WebClient();
        string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + passWord));
        client.Headers[HttpRequestHeader.Authorization] = $"Basic {credentials}";
        //If you have your data stored in an object serialize it into json to pass to the webclient with Newtonsoft JsonConvert
        var encodedJson = JsonConvert.SerializeObject(newAccount);

        client.Headers.Add($"x-api-key:{ApiKey}");
        client.Headers.Add("Content-Type:application/json");
        try
        {
            var response = client.UploadString($"{apiurl}", encodedJson);
            //if you have a model to deserialize the json into Newtonsoft will help bind the data to the model, this is an extremely useful trick for GET calls when you have a lot of data, you can strongly type a model and dump it into an instance of that class.
            Response response1 = JsonConvert.DeserializeObject<Response>(response);

Ответ 6

Простой (однострочный, без проверки ошибок, без ожидания ответа) решение, которое я нашел до сих пор

(new WebClient()).UploadStringAsync(new Uri(Address), dataString);‏

используйте с осторожностью!

Ответ 7

В этом решении используются только стандартные вызовы .NET.

Проверено:

  • Используется в корпоративном приложении WPF. Использует async/await, чтобы избежать блокировки пользовательского интерфейса.
  • Совместим с .NET 4. 5+.
  • Протестировано без параметров (требуется "GET" за кулисами).
  • Протестировано с параметрами (требуется "POST" за кулисами).
  • Протестировано на стандартной веб-странице, такой как Google.
  • Протестировано с внутренним веб-сервисом на основе Java.

Ссылка:

// Add a Reference to the assembly System.Web

Код:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;

private async Task<WebResponse> CallUri(string url, TimeSpan timeout)
{
    var uri = new Uri(url);
    NameValueCollection rawParameters = HttpUtility.ParseQueryString(uri.Query);
    var parameters = new Dictionary<string, string>();
    foreach (string p in rawParameters.Keys)
    {
        parameters[p] = rawParameters[p];
    }

    var client = new HttpClient { Timeout = timeout };
    HttpResponseMessage response;
    if (parameters.Count == 0)
    {
        response = await client.GetAsync(url);
    }
    else
    {
        var content = new FormUrlEncodedContent(parameters);
        string urlMinusParameters = uri.OriginalString.Split('?')[0]; // Parameters always follow the '?' symbol.
        response = await client.PostAsync(urlMinusParameters, content);
    }
    var responseString = await response.Content.ReadAsStringAsync();

    return new WebResponse(response.StatusCode, responseString);
}

private class WebResponse
{
    public WebResponse(HttpStatusCode httpStatusCode, string response)
    {
        this.HttpStatusCode = httpStatusCode;
        this.Response = response;
    }
    public HttpStatusCode HttpStatusCode { get; }
    public string Response { get; }
}

Для вызова без параметров (используется "GET" за кулисами):

 var timeout = TimeSpan.FromSeconds(300);
 WebResponse response = await this.CallUri("http://www.google.com/", timeout);
 if (response.HttpStatusCode == HttpStatusCode.OK)
 {
     Console.Write(response.Response); // Print HTML.
 }

Для вызова с параметрами (используется "POST" за кулисами):

 var timeout = TimeSpan.FromSeconds(300);
 WebResponse response = await this.CallUri("http://example.com/path/to/page?name=ferret&color=purple", timeout);
 if (response.HttpStatusCode == HttpStatusCode.OK)
 {
     Console.Write(response.Response); // Print HTML.
 }

Ответ 8

Вам нужно использовать класс WebRequest и GetRequestStream.

Здесь приведен пример.

Ответ 9

При использовании пространства имен Windows.Web.Http для POST вместо FormUrlEncodedContent мы пишем HttpFormUrlEncodedContent. Также ответ является типом HttpResponseMessage. Остальное как записал Эван Мулавски.

Ответ 10

Вы можете использовать IEnterprise.Easy-HTTP, так как он имеет встроенный разбор классов и построение запросов:

await new RequestBuilder<ExampleObject>()
.SetHost("https://httpbin.org")
.SetContentType(ContentType.Application_Json)
.SetType(RequestType.Post)
.SetModelToSerialize(dto)
.Build()
.Execute();

Ответ 11

Если вам нравится свободный API, вы можете использовать Tiny.RestClient. Доступно на Nuget

var client = new TinyRestClient(new HttpClient(), "http://MyAPI.com/api");
// POST
var city = new City() { Name = "Paris", Country = "France" };
// With content
var response = await client.PostRequest("City", city)
                           .ExecuteAsync<bool>();

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

Ответ 12

Создайте новый класс и вставьте его:

public class WebAPI : IDisposable
{
    private readonly string mUri;
    private readonly string mMethod;
    private readonly string[] mValues;
    private WebClient webClient = new WebClient();

    void IDisposable.Dispose()
    {
        webClient.Dispose();
    }

    public WebAPI(string uri, string method, params string[] values)
    {
        mUri = uri;
        mMethod = method;
        mValues = values;
    }

    public async Task<string> WebResponseStringAsync()
    {
        if (mMethod == "post")
        {
            var data = new NameValueCollection();

            foreach (string value in mValues)
            {
                string[] getvalue = value.Split('=');
                data[getvalue[0]] = getvalue[1];
            }

            var response = await webClient.UploadValuesTaskAsync(new Uri(mUri), data);
            return Encoding.UTF8.GetString(response);
        }
        else if (mMethod == "get")
        {
            var response = await webClient.DownloadStringTaskAsync(new Uri(mUri));
            return response;
        }
        else
            throw new Exception("Invalid method. You should to choose GET or POST method.");
    }

    public async Task<byte[]> WebResponseDataAsync()
    {
        if (mMethod == "post")
        {
            var data = new NameValueCollection();

            foreach (string value in mValues)
            {
                string[] getvalue = value.Split('=');
                data[getvalue[0]] = getvalue[1];
            }

            var response = await webClient.UploadValuesTaskAsync(new Uri(mUri), data);
            return response;
        }
        else if (mMethod == "get")
        {
            var response = await webClient.DownloadDataTaskAsync(new Uri(mUri));
            return response;
        }
        else
            throw new Exception("Invalid method. You should to choose GET or POST method.");
    }

    public string WebResponseString()
    {
        if (mMethod == "post")
        {
            var data = new NameValueCollection();

            foreach (string value in mValues)
            {
                string[] getvalue = value.Split('=');
                data[getvalue[0]] = getvalue[1];
            }

            var response = webClient.UploadValues(new Uri(mUri), data);
            return Encoding.UTF8.GetString(response);
        }
        else if (mMethod == "get")
        {
            var response = webClient.DownloadString(new Uri(mUri));
            return response;
        }
        else
            throw new Exception("Invalid method. You should to choose GET or POST method.");
    }

    public byte[] WebResponseData()
    {
        if (mMethod == "post")
        {
            var data = new NameValueCollection();

            foreach (string value in mValues)
            {
                string[] getvalue = value.Split('=');
                data[getvalue[0]] = getvalue[1];
            }

            var response = webClient.UploadValues(new Uri(mUri), data);
            return response;
        }
        else if (mMethod == "get")
        {
            var response = webClient.DownloadData(new Uri(mUri));
            return response;
        }
        else
            throw new Exception("Invalid method. You should to choose GET or POST method.");
    }
}

Как использовать синхронизацию:

string content; // string
byte[] content; // byte array

using (WebAPI webAPI = new WebAPI(URL, "post", values)) // POST
{
    content = webAPI.WebResponseString(); // string
    content = webAPI.WebResponseData(); // byte array          
}

using (WebAPI webAPI = new WebAPI(URL, "get")) // GET
{
    content = webAPI.WebResponseString(); // string
    content = webAPI.WebResponseData(); // byte array          
}

Как использовать Async:

string content; // string
byte[] content; // byte array

using (WebAPI webAPI = new WebAPI(URL, "post", values)) // POST
{
    content = await webAPI.WebResponseStringAsync(); // string
    content = await webAPI.WebResponseDataAsync(); // byte array          
}

using (WebAPI webAPI = new WebAPI(URL, "get")) // GET
{
    content = await webAPI.WebResponseStringAsync(); // string
    content = await webAPI.WebResponseDataAsync(); // byte array          
}

Не забудьте вставить ключевое слово "async" в вашу функцию, например:

private async void PrintButton_ClickEvent(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    // your code ...
}

"values" - это строковый массив (вы можете добавить бесконечные параметры), например:

string[] values = { "username=pinco", "password=pallino", "age=20", "gender=male" };