.net Core 使用IHttpClientFactory请求实现

来源:脚本之家  责任编辑:小易  

在.Net 4.5中增加了一个新的System.Net.Http.HttpClient名字空间(在

     导读:本文已添加在 晨曦微服务之旅 ,现在自己在尝试微服务架构,一边学边做项目快速的进入状态。当然在学习的过程中会将自己学到的知识进行分享。

一、简介HttpClient是Apache Jakarta Common下的子项目,用来

一、为什么不用HttpClient

//遇到同样的问题,已经解决方式是通过设置的 HttpContent 的 Headers.Conte

        1.HttPClient使用完之后不会立即关闭开启网络连接时会占用底层socket资源,但在HttpClient调用其本身的Dispose方法时,并不能立刻释放该资源

使用方法使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。1. 创

2.如果频繁的使用HttpClient,频繁的打开链接,关闭链接消耗就会很大。

import java.io.IOException;import net.sf.json.

二、解决方案

灰色原意是灰尘的颜色。它介于黑与白之间,没有黑色与白色那么强烈的视觉冲击感,更能给人低调奢华的贵族气质。而且灰色不挑肤色,不挑年龄,也更能经得起时间的考验,百搭又时髦。灰色有着各种浓淡色调的变化,搭配起来自有一种说不出的魅力。怪不得越来越多的人称它为“高级灰”!下面就和西小怪一起来看看怎样把灰色穿出高级感吧!?颜色搭配灰+黑一身黑难免显得有些太过沉闷,而当黑色中和了灰色端庄的气质,看起来就有了一种高级随性、干练霸气的感觉,简约时尚又不失低调内敛!灰+白干净的白色和灰色也是最安全的搭配手法!比起黑色,灰色跟白色搭配起来则显得更加明亮、轻盈。白色还能够带走灰色过于低调的感觉,增添青春感,让人看起来

        1.我们可以延长HttpClient的生命周期,比如对其建一个静态的对象

谢邀!《刺客列传》里,整部剧的人物感觉是怎样的?那么,接下来就按照我自己的观点谈谈这部《刺客列传》首先,一开始,我确实是阿离粉,但是重看了不下五遍之后,我是每一个人的粉每个人都真心爱到不行,**卧里个大槽每个角色真心很对我胃口啊,都很人性化,没有玛丽苏杰克苏,凭本事凭计谋,有自己想要的自己的私心而不是什么为了世界什么的大爱,表示神烦这种,被黑的最惨的莫过于两个角色,方方土,慕容离,一个背着弑君渣男的名称,一个因为报复世界害了其它粉的心头宝。仲堃仪,喜欢的最慢的一个角色,但是后期真的喜欢的不行,演技各种棒,回看一次就会发现那些眼神的变化,阴谋诡计什么的也特别喜欢,楼主比较喜欢接地气的人物,不喜欢

private static HttpClient Client = new HttpClient();

被时光掩埋的秘密——我的乡愁不知从什么时候开始,乡愁开始在心中蔓延,与为赋新词强说愁不同,它是一种真实而强烈的感觉,如水波涟漪般徐徐荡开,风中花瓣般轻轻坠落家,非不能回,所痛苦的原因是,自己能力的有限,不能够为家乡的一草一木再添砖加瓦,我曾有过无数的设想,有一天可荣归故里,我当散尽钱财,把故乡打造成我所想象的样子:嗯,这里应该有一条曲径通幽的羊肠小道,这里应该建个小木屋,屋角再放些柴禾,这样在寒冷的冬季,我就可以伪装出一副柴门闻犬吠,风雪夜归人的味道。哦,那条小河要把它修葺一新,最好再架起一座浮桥。最后我还要凭一己之力,修一条横贯南北的火车道,就算在我们这偏僻的乡下,也会像日本的北

2.或者使用单例模式,至于你使用哪一种单例模式就看你自己了,这里就不细将了。因为这样感觉起来不是很舒服

维多利亚的秘密大秀每年这个时候都要占满时尚媒体的大头条,作为一枚颇具好奇心的未婚男子,我有点点搞不懂,虽然维密大秀好看,但是真的有女性朋友们穿维密的内衣吗?“穿,我是忠实粉哦。”D姐姐这么说。Daisy姐姐是我的编辑,当年她出差去美国,回来就给编辑部的男生带巧克力,给女生每人带一条维密。“平价,款式又好看,穿得又很舒服,当然会喜欢啦。”D姐姐这么说。什么?平价?我有点点没搞明白,每次看维密大秀的时候,亮点除了维密天使的好身材之外,难道不是那些镶满水晶/钻石/蓝宝石/红宝石的天价胸罩吗?经过D姐姐这么一点拨,我才理解了,维多利亚的秘密的定位可能有点像内衣界的H&M或者Zara,秀场上的那

三、HttpClientFactory

        1.在.NET Core 2.1版本之后引入的 HttpClientFactory解决了HttpClient的所有痛点。有了 HttpClientFactory,我们不需要关心如何创建HttpClient,又如何释放它。通过它可以创建具有特定业务的HttpClient,而且可以很友好的和 DI 容器结合使用,更为灵活。

2.HttpClientFactory 创建的HttpClient,也即是HttpClientHandler,只是这些个HttpClient被放到了“池子”中,工厂每次在create的时候会自动判断是新建还是复用。(默认生命周期为2min,默认的生命周期可以修改)

//修改默认的生命周期 services.AddHttpClient() .SetHandlerLifetime(TimeSpan.FromMinutes(5));

四、HttpClientFactory的使用

一、第一种使用方式

在Startup.cs中进行注册

//注册http请求服务 services.AddHttpClient();

2.Httphelper请求辅助类中使用

/// <summary> /// 注入http请求 /// </summary> private readonly IHttpClientFactory httpClientFactory; public HttpHelp(IHttpClientFactory _httpClientFactory) { httpClientFactory = _httpClientFactory; } // <summary> // Get请求数据 // <para>最终以url参数的方式提交</para> // </summary> // <param name="parameters">参数字典,可为空</param> // <param name="requestUri">例如/api/Files/UploadFile</param> // <returns></returns> public async Task<string> Get(Dictionary<string, string> parameters, string requestUri, string token) { //从工厂获取请求对象 var client = httpClientFactory.CreateClient(); //添加请求头 if (!string.IsNullOrWhiteSpace(token)) { client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); } client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8"); //拼接地址 if (parameters != null) { var strParam = string.Join("&", parameters.Select(o => o.Key + "=" + o.Value)); requestUri = string.Concat(requestUri, '?', strParam); } client.BaseAddress = new Uri(requestUri); return client.GetStringAsync(requestUri).Result; }

3.然后我们在Startup.cs对相对的类进行注册就可以了使用了。

二、使用命名客户端

1.在Startup.cs中进行注册, 这个注册可以存在多个 。以创建名字区分

services.AddHttpClient("github", c => { c.BaseAddress = new Uri("https://xxxxxxx.com/"); // Github API versioning c.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8"); // Github requires a user-agent c.DefaultRequestHeaders.Add("Authorization", "asfasfasdsgdsfsdfsdafasfas"); });

2.使用方式和上面的一样只要

/// <summary> /// 注入http请求 /// </summary> private readonly IHttpClientFactory httpClientFactory; public HttpHelp(IHttpClientFactory _httpClientFactory) { httpClientFactory = _httpClientFactory; } // <summary> // Get请求数据 // <para>最终以url参数的方式提交</para> // </summary> // <param name="parameters">参数字典,可为空</param> // <param name="requestUri">例如/api/Files/UploadFile</param> // <returns></returns> public async Task<string> Get(Dictionary<string, string> parameters, string requestUri, string token) { //从工厂获取请求对象 声明自己创建哪一个httpClient客户端 var client = httpClientFactory.CreateClient("github"); //添加请求头 if (!string.IsNullOrWhiteSpace(token)) { client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); } client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8"); //拼接地址 if (parameters != null) { var strParam = string.Join("&", parameters.Select(o => o.Key + "=" + o.Value)); requestUri = string.Concat(requestUri, '?', strParam); } client.BaseAddress = new Uri(requestUri); return client.GetStringAsync(requestUri).Result; }

三、类型化客户端

1.创建一个类

public class HttpClienService { public HttpClient Client { get; } public HttpClienService(HttpClient client) { client.BaseAddress = new Uri("https://xxxx.com/"); // GitHub API versioning client.DefaultRequestHeaders.Add("Authorization", "xxxxxxxxxxxx"); // GitHub requires a user-agent client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8"); Client = client; } //这个下面就是编写自己方法,进行调用 }

2.在Startup.cs中进行注册, 这个注册可以存在多个。

services.AddHttpClient<classHttp>(); //注册之后,使用依赖注入的方式进行注入,进行使用。

扩展阅读,根据您访问的内容系统为您准备了以下内容,希望对您有帮助。

如何创建httpclientfactory

方法/步骤

下载httpclient

百度一下:apache httpclient,还是看截图吧

直接上代码,做一个创建client的工具类

public static CloseableHttpClient createSSLClientDefault(){

try {

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {

//信任所有

public boolean isTrusted(X509Certificate[] chain,

String authType) throws CertificateException {

return true;

}

}).build();

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);

return HttpClients.custom().setSSLSocketFactory(sslsf).build();

} catch (KeyManagementException e) {

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (KeyStoreException e) {

e.printStackTrace();

}

return HttpClients.createDefault();

}

终于知道什么情况下需要实现.NET Core中的IOptions接口

我们所说的ApplicationBuilder是对所有实现了IApplicationBuilder接口的所有类型及其对象的统称。注册到WebHostBuilder上的启动类型具有一个用于管道定值的Configure方法,它利用作为参数的ApplicationBuilder对象进行中间件的注册。由于ApplicationBuilder与组成管道的中间件具有直接的关系,所以我们得先来说说中间件在管道中究竟体现为一个怎样的对象。中间件在请求处理流程中体现为一个类型为Func的委托对象,对于很多刚刚接触请求处理管道的读者朋友们来说,可能一开始对此有点难以理解,所以容来略作解释。我们上面已经提到过RequestDelegate这么一个委托,它相当于一个Func对象,该委托对象表示针对提供的HttpContext所做进行一项处理操作,这项操作代表某个中间件针对请求的处理。那为何我们不直接用一个RequestDelegate对象来表示一个中间件,而将它表示成一个Func对象呢?在大部分应用中,我们会针对具体的请求处理需求注册多个不同的中间件,这些中间件按照注册时间的先后顺序进行排列进而构成我们所谓的请求处理管道。对于某个中间件来说,在它完成了自身的请求处理任务之后,需要将请求传递给下一个中间件作后续的处理。Func中作为输入参数的RequestDelegate对象代表一个委托链,体现了后续中间件对请求的处理,当前中间件将自身实现的请求处理任务添加到这个委托链中,而返回RequestDelegate对象代表最新的委托链。以右图所示的管道为例,如果用一个Func来表示中间件B,那么作为输入参数的RequestDelegate对象代表的是C对请求的处理操作,而返回值则代表B和C先后对请求处的处理操作。如果一个Func代表第一个从服务器接收请求的中间件(比如A),那么执行该委托对象返回的RequestDelegate实际上体现了整个管道对请求的处理。在对中间件有了充分的了解之后,我们来看看用于注册中间件的IApplicationBuilder接口的定义。如下所示的是经过裁剪后的IApplicationBuilder接口的定义,我们只保留了两个核心的方法,其中Use方法实现了针对中间件的注册,另一个Build方法则将所有注册的中间件转换成一个RequestDelegate对象。1:publicinterfaceIApplicationBuilder2:{3:RequestDelegateBuild();4:IApplicationBuilderUse(Funcmiddleware);5:}从编程便利性考虑,很多预定义的中间件都具有用于注册的扩展方法,比如我们调用扩展方法UseStaticFiles来注册处理静态文件请求的中间件。对于我们演示的发布图片的应用来说,它也是通过调用一个具有如下定义的扩展方法UseImages来注册处理图片请求的中间件。1:publicstaticclassApplicationBuilderExtensions2:{3:publicstaticIApplicationBuilderUseImages(thisIApplicationBuilderapp,stringdirectory)4:{5:Funcmiddleware=next=>6:{7:returncontext=>8:{9:stringfileName=context.Request.Url.LocalPath.TrimStart('/');10:if(string.IsNullOrEmpty(Path.GetExtension(fileName)))11:{12:fileName+=".jpg";13:}14:fileName=Path.Combine(directory,fileName);15:context.Response.WriteFile(fileName,"image/jpg");16:returnnext(context);17:};18:};19:returnapp.Use(middleware);20:}21:}ASP.NETCore默认使用的是一个类型为ApplicationBuilder的对象来注册中间件,我们采用如下的代码片断来模拟它的实现逻辑。我们采用一个List>对象来存放所有注册的中间件,并调用Aggregate方法将它转换成一个RequestDelegate对象。1:publicclassApplicationBuilder:IApplicationBuilder2:{3:privateIList>middlewares=newList>();4:5:publicRequestDelegateBuild()6:{7:RequestDelegateseed=context=>Task.Run(()=>{});8:returnmiddlewares.Reverse().Aggregate(seed,(next,current)=>current(next));9:}10:11:publicIApplicationBuilderUse(Funcmiddleware)12:{13:middlewares.Add(middleware);14:returnthis;15:}16:}ASP.NETCore并不会直接创建ApplicationBuilder对象来注册中间件,而是利用对应的工厂来创建它。创建爱你ApplicationBuilder的工厂通过接口IApplicationBuilderFactory表示,在模拟的管道中我们将这个接口简化成如下的形式,该接口的默认实现者ApplicationBuilderFactory会直接创建一个ApplicationBuilder类型的对象。1:publicinterfaceIApplicationBuilderFactory2:{3:IApplicationBuilderCreateBuilder();4:}5:6:publicclassApplicationBuilderFactory:IApplicationBuilderFactory7:{8:publicIApplicationBuilderCreateBuilder()9:{10:returnnewApplicationBuilder();11:}12:}

使用httpClient请求接口报401 unauthorized

不是网上看的,要看实际情况,先用chrome F12看看,正常调用情况,看看认证方式

是Authorization Basic还是cookies 都可以解决的追问

怎么才能判断是哪种认证方式讷?是请求头中包含什么信息嘛还是?下面是F12捕捉到的信息,我对http这块所知不多,求大神相助...

下面没有截到的是参数,因为是get请求,所以参数在url上就可以看到了。voucherNo:Q132080390000616884920

从调用API接口 看.net framework和 net core的异同

由于.net core是跨平台使用的,所有微软重写好多API,由此有些差异也是正常的。

现在就来看下请求API的差别吧。

首先,原本的.net framework请求方法:

复制代码

public static T HttpPostWithDecompression<T>(string request, string url, int timeout) where T : new()

{

var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

httpWebRequest.Proxy = null;

httpWebRequest.Timeout = timeout;

httpWebRequest.Method = "POST";

httpWebRequest.ContentType = "application/json";

httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

var bytes = Encoding.UTF8.GetBytes(request);

Stream requestStream = null;

var responseContent = string.Empty;

try

{

requestStream = httpWebRequest.GetRequestStream();

requestStream.Write(bytes, 0, bytes.Length);

var webResponse = httpWebRequest.GetResponse();

var stream = webResponse.GetResponseStream();

if (stream != null)

{

var streamReader = new StreamReader(stream);

responseContent = streamReader.ReadToEnd();

streamReader.Close();

}

webResponse.Close();

return JsonConvert.DeserializeObject<T>(responseContent);

}

catch (Exception exception)

{

return new T();

}

finally

{

if (requestStream != null)

{

requestStream.Close();

}

}

}

复制代码

第一种返回错误编码的.net core的写法:

复制代码

public async static Task<T> HttpPostWithDecompression<T>(string request, string url, int timeout) where T : new()

{

var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

httpWebRequest.Proxy = null;

httpWebRequest.ContinueTimeout = timeout;

httpWebRequest.Method = "POST";

httpWebRequest.ContentType = "application/json";

httpWebRequest.Headers["Accept-Encoding"] = "gzip,deflate";

//httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

var data = Encoding.UTF8.GetBytes(request);

using (var requestStream = await httpWebRequest.GetRequestStreamAsync())//释放

{

requestStream.Write(data, 0, data.Length);

}

string result = string.Empty;

//响应流

using (var response = (HttpWebResponse)await httpWebRequest.GetResponseAsync())

{

Stream responseStream = null;

if (response.StatusCode == HttpStatusCode.OK)

{

responseStream = response.GetResponseStream();

if (responseStream != null)

{

var streamReader = new StreamReader(responseStream, Encoding.UTF8);

//获取返回的信息

result = streamReader.ReadToEnd();

return JsonConvert.DeserializeObject<T>(result);

}

}

}

return new T();

}

复制代码

查看下.net core下的属性和方法:

可以明显发现比.net framwork下少了好多。

也就是.net core的请求类型,更趋于向浏览器的请求头靠拢,也就是使用Headers字典(.net framwork下也有,但是同层级也会有一些属性,比如采用压缩)。

主要的区别就是 响应流 采用的是异步的方式,而.net framwork采用同步的方式,必须手动close(),而新的写法,就只能用using了。

但是,上述的这个方法,害死人了,请求也成功,就是编码始终调试不对,请求各位大神指点一二。

由于水平问题,未能解决上述问题,所以小弟采用.net core的 HttpClientHandler 类进行http请求:

get方法

复制代码

/// <summary>

/// get请求

/// </summary>

/// <param name="url">url包含参数</param>

public static async Task<T> doGet<T>(string url) where T : new()

{

var handler = new HttpClientHandler()

{

AutomaticDecompression = DecompressionMethods.GZip

};

using (var http = new HttpClient(handler))

{

var response = await http.GetAsync(url);

//确保HTTP成功状态值

response.EnsureSuccessStatusCode();

string responseStr =response.Content.ReadAsStringAsync().Result;

return JsonConvert.DeserializeObject<T>(responseStr);

}

}

复制代码

post请求

复制代码

/// <summary>

/// post请求

/// </summary>

/// <param name="url">url包含参数</param>

public async static Task<T> HttpPostWithDecompression<T>(string request, string apiUrl, int timeout) where T : new()

{

HttpClientHandler handler = new HttpClientHandler();

handler.Proxy = null;

handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

var data = Encoding.UTF8.GetBytes(request);

using (var httpClient = new HttpClient(handler))

{

httpClient.BaseAddress = new Uri(apiUrl);

httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var cont = new StringContent(request);

//var content = new FormUrlEncodedContent(JsonConvert.DeserializeObject<Dictionary<string, string>>(request));

//被上面这个注释掉的代码,这种偷懒转Dic的方式给坑苦了,不能这么用啊!!!

var response = await httpClient.PostAsync(apiUrl, cont);

string result = response.Content.ReadAsStringAsync().Result;

return JsonConvert.DeserializeObject<T>(result);

}

}

如何设置一个HttpClient的请求Content-Type头

PostMethod method = new PostMethod(ur);

method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");//本回答被提问者采纳

  • 本文相关:
  • .net core下http请求ihttpclientfactory示例详解
  • 通过asp.net实现flash对数据库的访问
  • dataset与datatable的区别示例介绍
  • 简单使用backgroundworker创建多个线程的教程
  • vs2010 水晶报表的使用方法
  • asp.net mvc webuploader实现上传功能
  • asp.net mvc图片上传前预览简单实现
  • 浅谈vs中的datapager分页
  • asp.net上传图片验证代码的小例子
  • abp入门系列之json格式化
  • 三种方法让response.redirect在新窗口打开
  • 如何创建httpclientfactory
  • 终于知道什么情况下需要实现.NET Core中的IOptions接口
  • 使用httpClient请求接口报401 unauthorized
  • 从调用API接口 看.net framework和 net core的异同
  • 如何设置一个HttpClient的请求Content-Type头
  • 新人求助 C#httpclient的使用方法
  • httpclient发送的请求客户端怎么接收
  • .Net HttpClient Headers.Add("Content-Type&quo...
  • 如何使用的HttpClient从网络API调用PUT方法
  • 如何获取 httpclient 请求json 参数
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved