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"));

//同步
Task.Run(() => 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 url = "https://files.cnblogs.com/files/RainFate/Net48Check.zip";
string fileFullPath = @"F:\DownLoad\Net48Check.zip";
HttpClient client = new HttpClient();
using HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
var StatusCode = response.StatusCode;
using Stream streamToReadFrom = await response.Content.ReadAsStreamAsync();
using Stream streamToWriteTo = File.Open(fileFullPath, FileMode.CreateNew);
await streamToReadFrom.CopyToAsync(streamToWriteTo);

添加请求头认证

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

代理

//Http代理
HttpMessageHandler httpClientHandler = new HttpClientHandler()
{
    Proxy = new WebProxy("ProxyUri")
};

//Socks代理
httpClientHandler = new SocketsHttpHandler()
{
    Proxy = new WebProxy("socks5://127.0.0.1:1080")
};

//Http代理携带用户名和密码
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();

HttpRequestMessage发送请求

var client = new HttpClient();
var request = new HttpRequestMessage
{
    Method = HttpMethod.Post,
    RequestUri = new Uri("https://www.baidu.com/"),
    Content = new StringContent("{ 'some': 'value' }", Encoding.UTF8, "application/json")
};
//request.Headers.Add();
var response =await client.SendAsync(request);
var responseContent = await response.Content.ReadAsStringAsync();

同步方法发送请求

var client = new HttpClient();
var response = Task.Run(() => client.GetAsync("https://www.baidu.com/")).Result;
if (response.IsSuccessStatusCode)
{
    string result = Task.Run(() => response.Content.ReadAsStringAsync()).Result;
}

使用Nito.AsyncEx同步方法调用异步方法,NuGet安装Nito.AsyncEx

namespace WebApplication3
{
    public static class AsyncHelper
    {
        public static TResult RunSync<TResult>(Func<Task<TResult>> func) => Nito.AsyncEx.AsyncContext.Run(func);

        public static void RunSync(Func<Task> action) => Nito.AsyncEx.AsyncContext.Run(action);
    }
}

使用HttpRequestMessage,需要.net5+

var client = new HttpClient();
var request = new HttpRequestMessage
{
    Method = HttpMethod.Post,
    RequestUri = new Uri("https://www.baidu.com/"),
    Content = new StringContent("{ 'some': 'value' }", Encoding.UTF8, "application/json")
};
//request.Headers.Add();
var response = client.Send(request);
using var reader = new StreamReader(response.Content.ReadAsStream());
var responseContent = reader.ReadToEnd();

NetCore中使用IHttpClientFactory

注册HttpClient


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpClient();

//根据HttpClientName添加不同的配置
builder.Services.AddHttpClient("HttpClientA", client =>
{
    client.BaseAddress = new Uri("http://127.0.0.1:5000");
    client.Timeout = TimeSpan.FromMinutes(5);
});

//添加HttpClientHandler
builder.Services.AddHttpClient("HttpClientB").ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
    // 如果服务器有 https 证书,但是证书不安全,则需要使用下面语句
    // => 也就是说,不校验证书,直接允许
    ServerCertificateCustomValidationCallback = delegate { return true; },
    //是否使用Cookie
    UseCookies = false
});


builder.Services.AddHttpClient("HttpClientC", client =>
{
    client.Timeout = TimeSpan.FromMinutes(1);
}).ConfigurePrimaryHttpMessageHandler(() =>
{
    var httpClientHandler = new HttpClientHandler
    {
        //解压缩
        AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
        //添加代理
        Proxy = new WebProxy
        {
            Address = new Uri("http://127.0.0.1:1080"),
            UseDefaultCredentials = false,
        },
        UseProxy = true
    };
    return httpClientHandler;
});

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

HttpContext 获取请求相关信息

需要注入IHttpContextAccessor。builder.Services.AddHttpContextAccessor();

private readonly IHttpContextAccessor _httpContextAccessor;
public void A()
{
    var context = _httpContextAccessor.HttpContext;
    if (context == null || context.Connection == null || context.Request == null)
    {
        return;
    }            

    //获取IServiceProvider
    var _serviceProvider = _httpContextAccessor.HttpContext.RequestServices;

    //判断Body是否存在
    var isBody = context.ActionDescriptor.Parameters.Any(r => r.BindingInfo?.BindingSource == BindingSource.Body);

    var request = context.Request;
    var ipAddress = context.Connection.RemoteIpAddress?.ToString();
    var requestHost = request.Host.Value;
    var requestPath = request.Path.Value;
    var requestQuery = request.QueryString.Value;
    //请求方式 http
    var requestScheme = request.Scheme;
    //请求地址
    var requestUrl = request.GetDisplayUrl();
    string url = request.Host + request.Path + request.QueryString;
    //请求方式
    string method = request.Method;
    //请求Header
    var requestHeadrs = request.Headers;
    var reqHeadDic = request.Headers.ToDictionary(x => x.Key, v => string.Join(";", v.Value));
    Dictionary<string, List<string>> reqHeadDic2 = request.Headers.ToDictionary(a => a.Key, a => a.Value.ToList());
    //请求Body,不能直接获取,需要在中间件获取
    var requestBody = string.Empty;
    //响应Header
    var responseHeadrs = context.Response.Headers;
    //响应Body,不能直接获取,需要在中间件获取
    var responseBody = string.Empty;
    //请求状态码
    var statusCode = context.Response.StatusCode;
    if (context?.User != null)
    {
        var userId = context.User.FindFirstValue("sub");
        var userName = context.User.Identity?.Name;
    }
}

获取请求头信息和服务

注入HttpContextAccessor

builder.Services.AddHttpContextAccessor();  

Controller获取请求头

        private readonly IHttpContextAccessor _httpContextAccessor;

        public WeatherForecastController(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        [HttpGet]
        public void Get()
        {
            //获取IServiceProvider
            var _serviceProvider = _httpContextAccessor.HttpContext.RequestServices;
            //获取服务
            var _logger= HttpContext.RequestServices.GetService<ILogger<WeatherForecastController>>();

            var headers = _httpContextAccessor.HttpContext!.Request.Headers;
            var reqHeadDic = headers.ToDictionary(x => x.Key, v => string.Join(";", v.Value));
            Dictionary<string, List<string>> reqHeadDic2 = Request.Headers.ToDictionary(a => a.Key, a => a.Value.ToList());
            var code = _httpContextAccessor.HttpContext.Request.Query["code"].ToString();
            var serverVars = HttpContext.GetServerVariable("SERVER_SOFTWARE");//获取请求服务器变量的值
        }

获取服务扩展类


    public sealed class HttpContextExtension
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        /// <summary>
        /// http context accessor
        /// </summary>
        public HttpContextExtension(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        /// <summary>
        /// 获取服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetRequiredService<T>() where T : notnull
        {
            return _httpContextAccessor.HttpContext.RequestServices.GetRequiredService<T>();
        }

        /// <summary>
        /// 获取服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public object GetRequiredService(Type serviceType)
        {
            return _httpContextAccessor.HttpContext.RequestServices.GetRequiredService(serviceType);
        }

        /// <summary>
        /// 获取服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetService<T>()
        {
            return _httpContextAccessor.HttpContext.RequestServices.GetService<T>();
        }

        /// <summary>
        /// 获取服务列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IEnumerable<object?> GetServices<T>(Type serviceType)
        {
            return _httpContextAccessor.HttpContext.RequestServices.GetServices(serviceType);
        }

        /// <summary>
        /// 获取服务列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IEnumerable<T> GetServices<T>()
        {
            return _httpContextAccessor.HttpContext.RequestServices.GetServices<T>();
        }
    }

请求中间件

使用中间件

app.UseMiddleware<LoggerMiddleware>();

中间件

using System.Text;

namespace WebApplication1
{
    public class LoggerMiddleware
    {
        private readonly RequestDelegate _next;

        public LoggerMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            if (context == null) return;

            var requestBody = await ReadRequestBody(context.Request);
            //Console.WriteLine($"Request Body: {requestBody}");

            using var originalBodyStream = context.Response.Body;
            using var responseStream = new MemoryStream();
            context.Response.Body = responseStream;

            await _next(context);

            var responseBody = await ReadResponseBody(context.Response);
            await responseStream.CopyToAsync(originalBodyStream);
            //Console.WriteLine($"Response Body: {responseBody}");
        }

        /// <summary>
        /// 读取RequestBody
        /// </summary>
        private static async Task<string> ReadRequestBody(HttpRequest request)
        {
            if (request.Method != HttpMethods.Post
                || request.ContentType == null
                || request.ContentLength== null
                || !(request.ContentLength > 0))
            {
                return string.Empty;
            }
            request.EnableBuffering();
            var body = request.Body;

            var buffer = new byte[Convert.ToInt32(request.ContentLength)];

            _ = await request.Body.ReadAsync(buffer, 0, buffer.Length);

            var bodyAsText = Encoding.UTF8.GetString(buffer);

            request.Body = body;
            request.Body.Seek(0, SeekOrigin.Begin);
            return bodyAsText;
        }

        /// <summary>
        /// 读取ResponseBody
        /// </summary>
        private static async Task<string> ReadResponseBody(HttpResponse response)
        {
            response.Body.Seek(0, SeekOrigin.Begin);

            if (response.ContentType == null)
            {
                return string.Empty;
            }
            var text = await new StreamReader(response.Body).ReadToEndAsync();
            response.Body.Seek(0, SeekOrigin.Begin);
            return text;
        }
    }
}

HttpClientHelper

using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

namespace WebApplication4
{
    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, Dictionary<string, string> arg = null,
            Dictionary<string, string> headerDic = null, string httpClientName = "default")
        {
            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;
            }
            return await DoRequest(requestUrl, null, headerDic, HttpMethod.Get, httpClientName: httpClientName);
        }

        /// <summary>
        /// Get请求,使用Basic认证
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="token">Jwt Token</param>
        /// <param name="arg">get请求url参数</param>
        /// <param name="headerDic">请求头</param>
        /// <returns></returns>
        public async Task<ResponseResult> DoGetWithBearer(string url, string token, Dictionary<string, string> arg = null,
            Dictionary<string, string> headerDic = null, string httpClientName = "default")
        {
            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;
            }
            return await DoRequest(requestUrl, null, headerDic, HttpMethod.Get, httpClientName: httpClientName, bearerAuthorization: token);
        }

        /// <summary>
        ///  Get请求, 使用Bearer认证
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="username"></param>
        /// <param name="pwd"></param>
        /// <param name="arg">get请求url参数</param>
        /// <param name="headerDic">请求头</param>
        /// <returns></returns>
        public async Task<ResponseResult> DoGetWithBasicAuthorization(string url, string username, string pwd, Dictionary<string, string> arg = null, Dictionary<string, string> headerDic = null, string httpClientName = "default")
        {
            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;
            }
            string basicAuthorization = $"{username}:{pwd}";
            return await DoRequest(requestUrl, null, headerDic, HttpMethod.Get, httpClientName: httpClientName, basicAuthorization: basicAuthorization);
        }

        /// <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, string httpClientName = "default")
            => await DoRequest(url, new StringContent(reqBody, Encoding.UTF8), headerDic, HttpMethod.Post, RequestFormat.Json, httpClientName);


        /// <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)
            => 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)
            => 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, string httpClientName = "default")
        {
            string reqBody = await new FormUrlEncodedContent(fromData).ReadAsStringAsync();
            return await DoRequest(url, new StringContent(reqBody, Encoding.UTF8), headerDic, HttpMethod.Post, RequestFormat.Form, httpClientName);
        }

        /// <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, string httpClientName = "default")
            => await DoRequest(url, streamContent, headerDic, httpMethod, RequestFormat.Stream, httpClientName);


        /// <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,
            string httpClientName = "default",
            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, httpClientName, 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)
            => await DoRequest(url, new StringContent(postJson, Encoding.UTF8), headerDic, HttpMethod.Put);


        /// <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)
            => await DoRequest(url, new StringContent(postJson, Encoding.UTF8), headerDic, HttpMethod.Delete);


        /// <summary>
        /// 发送请求
        /// </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, string httpClientName = "default", string boundary = "", string basicAuthorization = null, string bearerAuthorization = null)
        {
            HttpResponseMessage response;
            using var client = _httpClientFactory.CreateClient(httpClientName);

            if (url.StartsWith(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

            //为request添加basic授权凭据
            if (!string.IsNullOrWhiteSpace(basicAuthorization))
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(basicAuthorization)));

            //为request添加bearer授权凭证
            if (!string.IsNullOrWhiteSpace(bearerAuthorization))
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerAuthorization);


            if (httpMethod.Equals(HttpMethod.Get) || (content is StringContent && httpMethod.Equals(HttpMethod.Delete) && string.IsNullOrWhiteSpace(await content.ReadAsStringAsync())))
            {
                if (headerDic != null) foreach (var item in headerDic) client.DefaultRequestHeaders.Add(item.Key, item.Value);
                response = httpMethod.Equals(HttpMethod.Get) ? await client.GetAsync(url) : await client.DeleteAsync(url);
                return await ReadResponseResult(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);
            var message = new HttpRequestMessage
            {
                Method = httpMethod,
                Content = content,
                RequestUri = new Uri(url)
            };
            response = await client.SendAsync(message);
            return await ReadResponseResult(response);
        }

        /// <summary>
        /// 获取响应头List
        /// </summary>
        /// <param name="headers"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetHttpResponseHeadersDic(HttpResponseHeaders headers)
        {
            //return headers.ToDictionary(a => a.Key, a => a.Value.ToList());
            return headers.ToDictionary(x => x.Key, v => string.Join(";", v.Value));
        }

        /// <summary>
        /// 读取请求结果
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private async Task<ResponseResult> ReadResponseResult(HttpResponseMessage response)
        {
            var content = await response.Content.ReadAsStringAsync();
            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 => (int)HttpStatus >= 200 && (int)HttpStatus < 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
    }
}

第三方工具库

posted @ 2022-03-11 15:51  雨水的命运  阅读(1139)  评论(0编辑  收藏  举报