HttpClient
發送請求
其他請求同Post
Get
HttpClient client= new HttpClient();
//添加請求頭
client.DefaultRequestHeaders.Add("Key", "Value");
//請求頭添加其他值
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "");
client.DefaultRequestHeaders.Connection.Add(new("Keep-Alive"));
client.DefaultRequestHeaders.UserAgent.Add(new("Opera/8.0 (Macintosh; PPC Mac OS X; U; en)"));
client.DefaultRequestHeaders.Accept.Add(new ("text/html"));
client.DefaultRequestHeaders.AcceptCharset.Add(new ("utf-8"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new ("gzip,deflate"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new ("zh-CN,fr-FR;q=0.5"));
//同步
client.GetAsync("https://www.baidu.com").Result;
//異步
var response = await client.GetAsync("https://www.baidu.com");
Post
JSON請求
HttpClient client = new HttpClient();
string jsonBody = "{\"beijing\":{\"zone\":\"海淀\",\"zone_en\":\"haidian\"}}";
HttpContent content = new StringContent(jsonBody, System.Text.Encoding.UTF8);
//指定請求頭ContentType,其他類型需要變更ContentType
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json") { CharSet = "utf-8" };
//添加請求頭
content.Headers.Add("Key", "Value");
content.Headers.Add("Authorization", "token");
content.Headers.Add("Connection", "Keep-Alive");
content.Headers.Add("Accept", "text/html");
content.Headers.Add("Accept-Charset", "utf-8");
content.Headers.Add("Accept-Encoding", "gzip,deflate");
content.Headers.Add("Accept-Language", "zh-CN,fr-FR;q=0.5");
content.Headers.Add("User-Agent", "Opera/8.0 (Macintosh; PPC Mac OS X; U; en)");
var response = await client.PostAsync("https://www.baidu.com", content);
Form表單
HttpClient client = new HttpClient();
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("email", "email");
dict.Add("pwd", "pwd");
var formContent = new FormUrlEncodedContent(dict);
string reqBody = await formContent.ReadAsStringAsync();
HttpContent content = new StringContent(reqBody, System.Text.Encoding.UTF8);
//指定請求頭ContentType,其他類型需要變更ContentType
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded") { CharSet = "utf-8" };
var response = await client.PostAsync("https://www.baidu.com", content);
上傳文件/鍵值對Body
HttpClient client = new HttpClient();
var content = new MultipartFormDataContent();
content.Add(new StringContent("value"), "key");
byte[] File = null;
content.Add(new ByteArrayContent(File), "argName","FileName");
//指定請求頭ContentType,其他類型需要變更ContentType
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data") { CharSet = "utf-8" };
var response = await client.PostAsync("https://www.baidu.com", content);
上傳文件二進制流/Binary
HttpClient client = new HttpClient();
System.IO.Stream stream = null;
HttpContent content=new StreamContent(stream);
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream") { CharSet = "utf-8" };
var response = await client.PostAsync("https://www.baidu.com", content);
添加請求頭認證
string username = "admin";
string pwd = "123";
string basicAuthorization = $"{username}:{pwd}";
//爲request添加basic授權憑據
if (string.IsNullOrWhiteSpace(basicAuthorization) == false)
{
var byteArray = Encoding.ASCII.GetBytes(basicAuthorization);
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
}
string bearerAuthorization = string.Empty;
//爲request添加bearer授權憑證
if (string.IsNullOrWhiteSpace(bearerAuthorization) == false)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerAuthorization);
}
代理
var httpClientHandler = new HttpClientHandler()
{
//Proxy = new WebProxy("ProxyUri"),
Proxy = new WebProxy()
{
Address = new Uri("ProxyUri"),
BypassProxyOnLocal = false,
UseDefaultCredentials = false,
//服務器賬號密碼認證
Credentials = new NetworkCredential("userName", "password")
},
UseProxy = true
};
HttpClient client = new HttpClient(httpClientHandler);
響應結果處理
//判斷是否成功
if (response.IsSuccessStatusCode) { }
//獲取響應編碼
var responseStatusCodes = response.StatusCode;
//獲取響應頭
var responseHeaders = response.Headers;
var headersList = responseHeaders.GetValues("Set-Cookie").ToList();
string token = headersList.FirstOrDefault(a => a.Contains("token"));
List<KeyValuePair<string, string>> list = new();
foreach (var header in response.Headers.ToList())
{
foreach (var value in header.Value)
{
list.Add(new KeyValuePair<string, string>(header.Key, value));
}
}
//獲取響應結果
var responseContent = await response.Content.ReadAsStringAsync();
//獲取響應流
var responseStream = await response.Content.ReadAsStreamAsync();
NetCore中使用IHttpClientFactory
註冊HttpClient
//6.0-Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient();
//5.0-Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
}
Controller中構造函數注入
using Microsoft.AspNetCore.Mvc;
namespace WebApplication1.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly IHttpClientFactory _httpClientFactory;
public WeatherForecastController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
[HttpGet]
public string Get()
{
var client = _httpClientFactory.CreateClient();
var response = client.GetAsync("https://www.baidu.com").Result;
var responseContent = response.Content.ReadAsStringAsync().Result;
return responseContent;
}
}
}
ABP中注入
public IHttpClientFactory HttpClientFactory => LazyServiceProvider.LazyGetRequiredService<IHttpClientFactory>();
HttpClientHelper
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Text;
using System.Threading.Tasks;
namespace Helper
{
public class HttpClientHelper
{
private readonly IHttpClientFactory _httpClientFactory;
public HttpClientHelper(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
/// <summary>
/// Get請求
/// </summary>
/// <param name="url">請求地址</param>
/// <param name="arg">get請求url參數</param>
/// <param name="headerDic">請求頭</param>
/// <returns></returns>
public async Task<ResponseResult> DoGet(string url, IDictionary<string, string> arg = null,
IDictionary<string, string> headerDic = null, HttpClientHandler handler = null)
{
//構造參數
var requestUrl = url;
if (arg != null && arg.Count > 0)
{
string argStr = url.Contains("?") ? "&" : "?";
foreach (var item in arg)
{
argStr += item.Key + "=" + item.Value + "&";
}
argStr = argStr.TrimEnd('&');
requestUrl = url + argStr;
}
using var client = handler == null ? _httpClientFactory.CreateClient() : new HttpClient(handler);
//構造請求頭
if (headerDic != null)
{
foreach (var item in headerDic)
{
client.DefaultRequestHeaders.Add(item.Key, item.Value);
}
}
using var response = await client.GetAsync(requestUrl).ConfigureAwait(false);
var result = await ReadResponseResult(response).ConfigureAwait(false);
return result;
}
/// <summary>
/// Post請求
/// </summary>
/// <param name="url"></param>
/// <param name="reqBody"></param>
/// <param name="headerDic"></param>
/// <returns></returns>
public async Task<ResponseResult> DoPost(string url, string reqBody,
Dictionary<string, string> headerDic = null, HttpClientHandler handler = null)
{
return await DoRequest(url, new StringContent(reqBody, Encoding.UTF8), headerDic, HttpMethod.Post, RequestFormat.Json, handler);
}
/// <summary>
/// XML Post請求
/// </summary>
/// <param name="url"></param>
/// <param name="reqBody"></param>
/// <param name="headerDic"></param>
/// <returns></returns>
public async Task<ResponseResult> DoXmlPost(string url, string reqBody, Dictionary<string, string> headerDic = null)
{
return await DoRequest(url, new StringContent(reqBody, Encoding.UTF8), headerDic, HttpMethod.Post, RequestFormat.Xml);
}
/// <summary>
/// Text Post請求
/// </summary>
/// <param name="url"></param>
/// <param name="reqBody"></param>
/// <param name="headerDic"></param>
/// <returns></returns>
public async Task<ResponseResult> DoTextPost(string url, string reqBody, Dictionary<string, string> headerDic = null)
{
return await DoRequest(url, new StringContent(reqBody, Encoding.UTF8), headerDic, HttpMethod.Post, RequestFormat.Text);
}
/// <summary>
/// 提交Form Post請求
/// </summary>
/// <param name="url"></param>
/// <param name="fromData"></param>
/// <param name="headerDic"></param>
/// <returns></returns>
public async Task<ResponseResult> DoFormPost(string url,
Dictionary<string, string> fromData, Dictionary<string, string> headerDic = null, HttpClientHandler handler = null)
{
var content = new FormUrlEncodedContent(fromData);
string reqBody = await content.ReadAsStringAsync();
return await DoRequest(url, new StringContent(reqBody, Encoding.UTF8), headerDic, HttpMethod.Post, RequestFormat.Form, handler);
}
/// <summary>
/// Stream請求
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public async Task<ResponseResult> DoStreamRequest(string url,
HttpMethod httpMethod,
StreamContent streamContent,
Dictionary<string, string> headerDic = null,
HttpClientHandler handler = null)
{
return await DoRequest(url, streamContent, headerDic, httpMethod, RequestFormat.Stream, handler);
}
/// <summary>
/// 上傳File請求
/// </summary>
/// <param name="url"></param>
/// <param name="bodyDic">Body參數</param>
/// <param name="filelist">文件參數:文件流/參數名稱/文件名稱</param>
/// <param name="headerDic">請求頭</param>
/// <param name="handler">HttpClientHandler</param>
/// <param name="boundary">邊界符</param>
/// <returns></returns>
public async Task<ResponseResult> DoFileRequest(string url,
HttpMethod httpMethod,
Dictionary<string, string> bodyDic,
List<Tuple<byte[], string, string>> filelist,
Dictionary<string, string> headerDic = null,
HttpClientHandler handler = null,
string boundary = "")
{
var content = new MultipartFormDataContent();
if (bodyDic != null)
{
foreach (var item in bodyDic)
{
content.Add(new StringContent(item.Value), item.Key);
}
}
if (filelist != null)
{
foreach (var item in filelist)
{
content.Add(new ByteArrayContent(item.Item1), item.Item2, item.Item3);
}
}
return await DoRequest(url, content, headerDic, httpMethod, RequestFormat.MultipartForm, handler, boundary);
}
/// <summary>
/// Put請求
/// </summary>
/// <param name="url"></param>
/// <param name="postJson"></param>
/// <param name="headerDic"></param>
/// <returns></returns>
public async Task<ResponseResult> DoPut(string url, string postJson, Dictionary<string, string> headerDic = null)
{
return await DoRequest(url, new StringContent(postJson, Encoding.UTF8), headerDic, HttpMethod.Put).ConfigureAwait(false);
}
/// <summary>
/// Delete請求
/// </summary>
/// <param name="url"></param>
/// <param name="postJson"></param>
/// <param name="headerDic"></param>
/// <returns></returns>
public async Task<ResponseResult> DoDelete(string url, string postJson, Dictionary<string, string> headerDic = null)
{
return await DoRequest(url, new StringContent(postJson, Encoding.UTF8), headerDic, HttpMethod.Delete).ConfigureAwait(false);
}
/// <summary>
/// POST,PUT,DELETE請求
/// </summary>
/// <param name="url"></param>
/// <param name="reqBody"></param>
/// <param name="headerDic"></param>
/// <param name="httpMethod"></param>
/// <param name="contentType"></param>
/// <returns></returns>
private async Task<ResponseResult> DoRequest(string url, HttpContent content, Dictionary<string, string> headerDic,
HttpMethod httpMethod, RequestFormat contentType = RequestFormat.Json, HttpClientHandler handler = null, string boundary = "")
{
//handler ??= new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip };
HttpResponseMessage response;
string contentTypeStr = GetContentType(contentType, boundary);
content.Headers.ContentType = new MediaTypeHeaderValue(contentTypeStr) { CharSet = "utf-8" };
if (headerDic != null)
{
foreach (var item in headerDic)
{
content.Headers.Add(item.Key, item.Value);
}
}
using var client = handler == null ? _httpClientFactory.CreateClient() : new HttpClient(handler);
if (content is StringContent && httpMethod.Equals(HttpMethod.Delete))
{
if (string.IsNullOrWhiteSpace(await content.ReadAsStringAsync()))
{
if (headerDic != null)
foreach (var item in headerDic)
client.DefaultRequestHeaders.Add(item.Key, item.Value);
response = await client.DeleteAsync(url).ConfigureAwait(false);
return await ReadResponseResult(response).ConfigureAwait(false);
}
}
var message = new HttpRequestMessage
{
Method = httpMethod,
Content = content,
RequestUri = new Uri(url)
};
response = await client.SendAsync(message).ConfigureAwait(false);
return await ReadResponseResult(response).ConfigureAwait(false);
}
/// <summary>
/// 獲取響應頭List
/// </summary>
/// <param name="headers"></param>
/// <returns></returns>
public List<KeyValuePair<string, string>> GetHttpResponseHeadersList(HttpResponseHeaders headers)
{
List<KeyValuePair<string, string>> list = new();
foreach (var header in headers.ToList())
foreach (var value in header.Value)
list.Add(new KeyValuePair<string, string>(header.Key, value));
return list;
}
/// <summary>
/// 讀取請求結果
/// </summary>
/// <param name="response"></param>
/// <returns></returns>
private async Task<ResponseResult> ReadResponseResult(HttpResponseMessage response)
{
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var result = new ResponseResult(response.StatusCode, content, response.Headers);
return result;
}
/// <summary>
/// content type
/// </summary>
/// <param name="type"></param>
/// <param name="boundary">邊界符</param>
/// <returns></returns>
private static string GetContentType(RequestFormat type, string boundary = "")
{
string typeStr = "";
switch (type)
{
case RequestFormat.Json:
typeStr = "application/json";
break;
case RequestFormat.Form:
typeStr = "application/x-www-form-urlencoded";
break;
case RequestFormat.MultipartForm:
var tempboundary = string.IsNullOrWhiteSpace(boundary) == false
? boundary : DateTime.Now.Ticks.ToString("x");
typeStr = "multipart/form-data; boundary=" + tempboundary;
break;
case RequestFormat.Stream:
typeStr = "application/octet-stream";
break;
case RequestFormat.Xml:
typeStr = "application/xml";
break;
case RequestFormat.TextXml:
typeStr = "text/xml";
break;
case RequestFormat.Text:
typeStr = "text/plain";
break;
}
return typeStr;
}
}
/// <summary>
///響應的結果
/// </summary>
public class ResponseResult
{
/// <summary>
/// http狀態碼
/// </summary>
public HttpStatusCode HttpStatus { get; set; }
/// <summary>
/// 內容
/// </summary>
public string Content { get; set; }
/// <summary>
/// http響應請求頭
/// </summary>
public HttpResponseHeaders Headers { get; set; }
/// <summary>
/// 獲取請求是否成功
/// </summary>
public bool IsSuccess
{
get
{
var statusCode = (int)HttpStatus;
return statusCode >= 200 && statusCode < 400;
}
}
/// <summary>
/// 構造Json響應結果
/// </summary>
/// <param name="httpStatus"></param>
/// <param name="content"></param>
public ResponseResult(HttpStatusCode httpStatus, string content, HttpResponseHeaders headers)
{
if ((int)httpStatus >= 300)
{
throw new Exception("請求失敗:" + content + (int)httpStatus);
}
HttpStatus = httpStatus;
Content = content;
Headers = headers;
}
}
/// <summary>
/// 請求類型的枚舉
/// </summary>
enum RequestFormat
{
/// <summary>
/// json格式
/// </summary>
Json,
/// <summary>
/// form格式
/// </summary>
Form,
/// <summary>
/// 多內容的form格式
/// </summary>
MultipartForm,
/// <summary>
/// 流的格式
/// </summary>
Stream,
/// <summary>
///xml格式
/// </summary>
Xml,
/// <summary>
/// textxml
/// </summary>
TextXml,
/// <summary>
/// Text
/// </summary>
Text
}
}