如何进行HTTP POST Web请求

Hoo*_*och 1033 .net c# post httpwebrequest httprequest

如何使用该POST方法发出HTTP请求并发送一些数据?我可以做GET请求,但不知道如何制作POST.

Eva*_*ski 2009

有几种方法可以执行HTTP GETPOST请求:


方法A:HttpClient

适用于:.NET Framework 4.5 +,.NET Standard 1.1 +,.NET Core 1.0+

目前首选的方法.异步.通过NuGet提供的其他平台的便携版本.

using System.Net.Http;
Run Code Online (Sandbox Code Playgroud)

建立

它被推荐到一个实例HttpWebRequest为您的应用程序的生命周期和共享.

private static readonly HttpClient client = new HttpClient();
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

得到

var responseString = await client.GetStringAsync("http://www.example.com/recepticle.aspx");
Run Code Online (Sandbox Code Playgroud)

方法B:第三方库

RestSharp

经过试验和测试的库,用于与REST API交互.便携.可通过NuGet获得.

Flurl.Http

较新的图书馆提供流畅的API和测试助手.引擎盖下的HttpClient.便携.可通过NuGet获得.

using Flurl.Http;
Run Code Online (Sandbox Code Playgroud)

POST

var responseString = await "http://www.example.com/recepticle.aspx"
    .PostUrlEncodedAsync(new { thing1 = "hello", thing2 = "world" })
    .ReceiveString();
Run Code Online (Sandbox Code Playgroud)

得到

var responseString = await "http://www.example.com/recepticle.aspx"
    .GetStringAsync();
Run Code Online (Sandbox Code Playgroud)

方法C:遗产

适用于:.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
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

得到

var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx");

var response = (HttpWebResponse)request.GetResponse();

var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Run Code Online (Sandbox Code Playgroud)

方法D:WebClient(现在也是遗留的)

适用于:.NET Framework 1.1 +,.NET Standard 2.0 +,.NET Core 2.0+

using System.Net;
using System.Collections.Specialized;
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

得到

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

  • @Hiep:他们没有被弃用,只有更新(并且大多数情况下,更好,更灵活)的方式来制作Web请求.在我看来,对于简单的,非关键的操作,旧的方法很好 - 但这取决于你和你最熟悉的事情. (21认同)
  • 为什么你说WebRequest和WebClient是遗产?MSDN并未说它们已被弃用或任何其他内容.我错过了什么吗? (12认同)
  • 我讨厌击败死马,但你应该做`response.Result.Content.ReadAsStringAsync()` (6认同)
  • @Lloyd:`HttpWebResponse response =(HttpWebResponse)HttpWReq.GetResponse();` (2认同)
  • 为什么你甚至使用ASCII?如果有人需要带有UTF-8的xml怎么办? (2认同)
  • @GregA:不只是我。HttpClient的开发人员建议每个应用程序一个实例化。实际上,根据应用程序的功能,可能有必要实例化更多实例。仅仅因为它实现了“ IDisposable”,并不意味着您必须将其放在“ using”块中。 (2认同)
  • @DouglasFerreira的HttpClient和WebClient是HttpWebRequest的高层包装。真正的问题是何时使用`HttpClient`而不是`WebClient`(反之亦然);最好在/sf/ask/1437110671/#27737601中进行描述。 (2认同)

Pav*_*man 362

简单的GET请求

using System.Net;

...

using (var wb = new WebClient())
{
    var response = wb.DownloadString(url);
}
Run Code Online (Sandbox Code Playgroud)

简单的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);
}
Run Code Online (Sandbox Code Playgroud)

  • +1对于普通的东西POST,拥有如此短的代码是很棒的. (12认同)
  • 我想补充一点,POST请求的响应变量是一个字节数组.为了获得字符串响应,您只需执行Encoding.ASCII.GetString(response); (使用System.Text) (12认同)
  • Tim - 如果右键单击无法解析的文字,您将找到Resolve上下文菜单,其中包含为您添加Using语句的操作.如果Resolve上下文菜单未显示,则表示您需要先添加引用. (3认同)

Otá*_*cio 62

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Iva*_*nho 25

这是以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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*dam 7

这里有一些非常好的答案。让我发布一种不同的方法来使用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's 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);
Run Code Online (Sandbox Code Playgroud)


ikw*_*lem 7

还有另一种方法:

using (HttpClient httpClient = new HttpClient())
using (MultipartFormDataContent form = new MultipartFormDataContent())
{
    form.Add(new StringContent(param1), "param1");
    form.Add(new StringContent(param2), "param2");
    using (HttpResponseMessage response = await httpClient.PostAsync(url, form))
    {
        response.EnsureSuccessStatusCode();
        string res = await response.Content.ReadAsStringAsync();
        return res;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样您就可以轻松发布流。


小智 6

如果你喜欢流畅的 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>();
Run Code Online (Sandbox Code Playgroud)


Oha*_*hen 5

到目前为止,我已经找到了简单的(单线,没有错误检查,没有等待响应的)解决方案

(new WebClient()).UploadStringAsync(new Uri(Address), dataString);?
Run Code Online (Sandbox Code Playgroud)

谨慎使用!

  • 那真是太糟糕了。我不建议这样做,因为没有任何类型的错误处理,调试起来很痛苦。另外,这个问题已经有了很好的答案。 (5认同)

小智 5

当使用Windows.Web.Http命名空间时,对于 POST 而不是 FormUrlEncodedContent,我们编写 HttpFormUrlEncodedContent。响应也是 HttpResponseMessage 类型。其余的就像埃文穆拉夫斯基写的那样。


Con*_*ngo 5

该解决方案仅使用标准.NET调用。

经过测试:

  • 在企业WPF应用程序中使用。使用async / await避免阻塞UI。
  • 与.NET 4.5+兼容。
  • 无参数测试(在幕后需要“ GET”)。
  • 经过参数测试(在幕后需要“ POST”)。
  • 经过标准网页(例如Google)的测试。
  • 使用内部基于Java的Web服务进行了测试。

参考:

// Add a Reference to the assembly System.Web
Run Code Online (Sandbox Code Playgroud)

码:

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; }
}
Run Code Online (Sandbox Code Playgroud)

要不带任何参数的调用(在幕后使用“ 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.
 }
Run Code Online (Sandbox Code Playgroud)

要使用参数进行调用(在幕后使用“ 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.
 }
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

1474766 次

最近记录:

5 年,11 月 前