安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

在ASP。NETCore中使用IHttpClientFact

1月17日 乔了了投稿
  可以注册IHttpClientFactory并将其用于配置和创建应用中的HttpClient实例。IHttpClientFactory的优势如下:提供一个中心位置,用于命名和配置逻辑HttpClient实例。例如,可注册和配置名为github的客户端,使其访问GitHub。可以注册一个默认客户端用于一般性访问。通过HttpClient中的委托处理程序来编码出站中间件的概念。提供基于Polly的中间件的扩展,以利用HttpClient中的委托处理程序。管理基础HttpClientMessageHandler实例的池和生存期。自动管理可避免手动管理HttpClient生存期时出现的常见DNS(域名系统)问题。(通过ILogger)添加可配置的记录体验,以处理工厂创建的客户端发送的所有请求。
  查看或下载示例代码(如何下载)。
  此主题版本中的示例代码使用System。Text。Json来对HTTP响应中返回的JSON内容进行反序列化。对于使用Json。NET和ReadAsAsync的示例,请使用版本选择器选择此主题的2。x版本。消耗模式
  在应用中可以通过以下多种方式使用IHttpClientFactory:基本用法命名客户端类型化客户端生成的客户端
  最佳方法取决于应用要求。基本用法
  可以通过调用AddHttpClient来注册IHttpClientFactory:publicclassStartup{publicStartup(IConfigurationconfiguration){C}publicIConfigurationConfiguration{}publicvoidConfigureServices(IServiceCollectionservices){services。AddHttpClient();Remainingcodedeletedforbrevity。
  可以使用依赖项注入(DI)来请求IHttpClientFactory。以下代码使用IHttpClientFactory来创建HttpClient实例:publicclassBasicUsageModel:PageModel{privatereadonlyIHttpClientFactoryclientFpublicIEnumerableGitHubBranchBranches{}publicboolGetBranchesError{}publicBasicUsageModel(IHttpClientFactoryclientFactory){clientFactoryclientF}publicasyncTaskOnGet(){varrequestnewHttpRequestMessage(HttpMethod。Get,https:api。github。comreposdotnetAspNetCore。Docsbranches);request。Headers。Add(Accept,applicationvnd。github。v3json);request。Headers。Add(UserAgent,HttpClientFactorySample);varclientclientFactory。CreateClient();varresponseawaitclient。SendAsync(request);if(response。IsSuccessStatusCode){usingvarresponseStreamawaitresponse。Content。ReadAsStreamAsync();BranchesawaitJsonSerializer。DeserializeAsyncIEnumerableGitHubBranch(responseStream);}else{GetBranchesEBranchesArray。EmptyGitHubBranch();}}}
  像前面的示例一样,使用IHttpClientFactory是重构现有应用的好方法。这不会影响HttpClient的使用方式。在现有应用中创建HttpClient实例的位置,使用对CreateClient的调用替换这些匹配项。命名客户端
  在以下情况下,命名客户端是一个不错的选择:应用需要HttpClient的许多不同用法。许多HttpClient具有不同的配置。
  可以在Startup。ConfigureServices中注册时指定命名HttpClient的配置:services。AddHttpClient(github,c{c。BaseAddressnewUri(https:api。github。com);GithubAPIversioningc。DefaultRequestHeaders。Add(Accept,applicationvnd。github。v3json);Githubrequiresauseragentc。DefaultRequestHeaders。Add(UserAgent,HttpClientFactorySample);});
  在上述代码中,客户端配置如下:基址为https:api。github。com。使用GitHubAPI需要的两个标头。CreateClient
  每次调用CreateClient时:创建HttpClient的新实例。调用配置操作。
  要创建命名客户端,请将其名称传递到CreateClient中:publicclassNamedClientModel:PageModel{privatereadonlyIHttpClientFactoryclientFpublicIEnumerableGitHubPullRequestPullRequests{}publicboolGetPullRequestsError{}publicboolHasPullRequestsPullRequests。Any();publicNamedClientModel(IHttpClientFactoryclientFactory){clientFactoryclientF}publicasyncTaskOnGet(){varrequestnewHttpRequestMessage(HttpMethod。Get,reposdotnetAspNetCore。Docspulls);varclientclientFactory。CreateClient(github);varresponseawaitclient。SendAsync(request);if(response。IsSuccessStatusCode){usingvarresponseStreamawaitresponse。Content。ReadAsStreamAsync();PullRequestsawaitJsonSerializer。DeserializeAsyncIEnumerableGitHubPullRequest(responseStream);}else{GetPullRequestsEPullRequestsArray。EmptyGitHubPullRequest();}}}
  在上述代码中,请求不需要指定主机名。代码可以仅传递路径,因为采用了为客户端配置的基址。类型化客户端
  类型化客户端:提供与命名客户端一样的功能,不需要将字符串用作密钥。在使用客户端时提供IntelliSense和编译器帮助。提供单个位置来配置特定HttpClient并与其进行交互。例如,可以使用单个类型化客户端:对于单个后端终结点。封装处理终结点的所有逻辑。使用DI且可以被注入到应用中需要的位置。
  类型化客户端在构造函数中接受HttpClient参数:publicclassGitHubService{publicHttpClientClient{}publicGitHubService(HttpClientclient){client。BaseAddressnewUri(https:api。github。com);GitHubAPIversioningclient。DefaultRequestHeaders。Add(Accept,applicationvnd。github。v3json);GitHubrequiresauseragentclient。DefaultRequestHeaders。Add(UserAgent,HttpClientFactorySample);C}publicasyncTaskIEnumerableGitHubIssueGetAspNetDocsIssues(){returnawaitClient。GetFromJsonAsyncIEnumerableGitHubIssue(reposaspnetAspNetCore。Docsissues?stateopensortcreateddirectiondesc);}}
  在上述代码中:配置转移到了类型化客户端中。HttpClient对象公开为公共属性。
  可以创建特定于API的方法来公开HttpClient功能。例如,创建GetAspNetDocsIssues方法来封装代码以检索未解决的问题。
  以下代码调用Startup。ConfigureServices中的AddHttpClient来注册类型化客户端类:services。AddHttpClientGitHubService();
  使用DI将类型客户端注册为暂时客户端。在上述代码中,AddHttpClient将GitHubService注册为暂时性服务。此注册使用工厂方法执行以下操作:创建HttpClient的实例。创建GitHubService的实例,将HttpClient的实例传入其构造函数。
  可以直接插入或使用类型化客户端:publicclassTypedClientModel:PageModel{privatereadonlyGitHubServicegitHubSpublicIEnumerableGitHubIssueLatestIssues{}publicboolHasIssueLatestIssues。Any();publicboolGetIssuesError{}publicTypedClientModel(GitHubServicegitHubService){gitHubServicegitHubS}publicasyncTaskOnGet(){try{LatestIssuesawaitgitHubService。GetAspNetDocsIssues();}catch(HttpRequestException){GetIssuesELatestIssuesArray。EmptyGitHubIssue();}}}
  可以在Startup。ConfigureServices中注册时指定类型化客户端的配置,而不是在类型化客户端的构造函数中指定:services。AddHttpClientRepoService(c{c。BaseAddressnewUri(https:api。github。com);c。DefaultRequestHeaders。Add(Accept,applicationvnd。github。v3json);c。DefaultRequestHeaders。Add(UserAgent,HttpClientFactorySample);});
  可以将HttpClient封装在类型化客户端中,定义一个在内部调用HttpClient实例的方法,而不是将其公开为属性:publicclassRepoService{httpClientisntexposedpubliclyprivatereadonlyHttpClienthttpCpublicRepoService(HttpClientclient){httpC}publicasyncTaskIEnumerablestringGetRepos(){varresponseawaithttpClient。GetAsync(aspnetrepos);response。EnsureSuccessStatusCode();usingvarresponseStreamawaitresponse。Content。ReadAsStreamAsync();returnawaitJsonSerializer。DeserializeAsyncIEnumerablestring(responseStream);}}
  在上述代码中,HttpClient存储在私有字段中。通过公共GetRepos方法访问HttpClient。生成的客户端
  IHttpClientFactory可结合第三方库(例如Refit)使用。Refit是。NET的REST库。它将RESTAPI转换为实时接口。RestService动态生成该接口的实现,使用HttpClient进行外部HTTP调用。
  定义了接口和答复来代表外部API及其响应:publicinterfaceIHelloClient{〔Get(helloworld)〕TaskReplyGetMessageAsync();}publicclassReply{publicstringMessage{}}
  可以添加类型化客户端,使用Refit生成实现:publicvoidConfigureServices(IServiceCollectionservices){services。AddHttpClient(hello,c{c。BaseAddressnewUri(http:localhost:5000);})。AddTypedClient(cRefit。RestService。ForIHelloClient(c));services。AddControllers();}
  可以在必要时使用定义的接口,以及由DI和Refit提供的实现:〔ApiController〕publicclassValuesController:ControllerBase{privatereadonlyIHelloCpublicValuesController(IHelloClientclient){}〔HttpGet()〕publicasyncTaskIndex(){returnawaitclient。GetMessageAsync();}}发出POST、PUT和DELETE请求
  在前面的示例中,所有HTTP请求均使用GETHTTP谓词。HttpClient还支持其他HTTP谓词,其中包括:POSTPUT删除PATCH
  有关受支持的HTTP谓词的完整列表,请参阅HttpMethod。
  下面的示例演示如何发出HTTPPOST请求:publicasyncTaskCreateItemAsync(TodoItemtodoItem){vartodoItemJsonnewStringContent(JsonSerializer。Serialize(todoItem,jsonSerializerOptions),Encoding。UTF8,applicationjson);usingvarhttpResponseawaithttpClient。PostAsync(apiTodoItems,todoItemJson);httpResponse。EnsureSuccessStatusCode();}
  在前面的代码中,CreateItemAsync方法:使用System。Text。Json将TodoItem参数序列化为JSON。这将使用JsonSerializerOptions的实例来配置序列化过程。创建StringContent的实例,以打包序列化的JSON以便在HTTP请求的正文中发送。调用PostAsync将JSON内容发送到指定的URL。这是添加到HttpClient。BaseAddress的相对URL。如果响应状态代码不指示成功,则调用EnsureSuccessStatusCode引发异常。
  HttpClient还支持其他类型的内容。例如,MultipartContent和StreamContent。有关受支持的内容的完整列表,请参阅HttpContent。
  下面的示例演示了一个HTTPPUT请求:publicasyncTaskSaveItemAsync(TodoItemtodoItem){vartodoItemJsonnewStringContent(JsonSerializer。Serialize(todoItem),Encoding。UTF8,applicationjson);usingvarhttpResponseawaithttpClient。PutAsync(34;apiTodoItems{todoItem。Id},todoItemJson);httpResponse。EnsureSuccessStatusCode();}
  前面的代码与POST示例非常相似。SaveItemAsync方法调用PutAsync而不是PostAsync。
  下面的示例演示了一个HTTPDELETE请求:publicasyncTaskDeleteItemAsync(longitemId){usingvarhttpResponseawaithttpClient。DeleteAsync(34;apiTodoItems{itemId});httpResponse。EnsureSuccessStatusCode();}
  在前面的代码中,DeleteItemAsync方法调用DeleteAsync。由于HTTPDELETE请求通常不包含正文,因此DeleteAsync方法不提供接受HttpContent实例的重载。
  要详细了解如何将不同的HTTP谓词用于HttpClient,请参阅HttpClient。出站请求中间件
  HttpClient具有委托处理程序的概念,这些委托处理程序可以链接在一起,处理出站HTTP请求。IHttpClientFactory:简化定义应用于各命名客户端的处理程序。支持注册和链接多个处理程序,以生成出站请求中间件管道。每个处理程序都可以在出站请求前后执行工作。此模式:类似于ASP。NETCore中的入站中间件管道。提供一种机制来管理有关HTTP请求的横切关注点,例如:缓存错误处理序列化日志记录
  创建委托处理程序:派生自DelegatingHandler。重写SendAsync。在将请求传递至管道中的下一个处理程序之前执行代码:publicclassValidateHeaderHandler:DelegatingHandler{protectedoverrideasyncTaskHttpResponseMessageSendAsync(HttpRequestMessagerequest,CancellationTokencancellationToken){if(!request。Headers。Contains(XAPIKEY)){returnnewHttpResponseMessage(HttpStatusCode。BadRequest){ContentnewStringContent(YoumustsupplyanAPIkeyheadercalledXAPIKEY)};}returnawaitbase。SendAsync(request,cancellationToken);}}
  上述代码检查请求中是否存在XAPIKEY标头。如果缺失XAPIKEY,则返回BadRequest。
  可使用Microsoft。Extensions。DependencyInjection。HttpClientBuilderExtensions。AddHttpMessageHandler将多个处理程序添加到HttpClient的配置中:publicvoidConfigureServices(IServiceCollectionservices){services。AddTransientValidateHeaderHandler();services。AddHttpClient(externalservice,c{AssumethisisanexternalservicewhichrequiresanAPIKEYc。BaseAddressnewUri(https:localhost:5001);})。AddHttpMessageHandlerValidateHeaderHandler();Remainingcodedeletedforbrevity。
  在上述代码中通过DI注册了ValidateHeaderHandler。注册后可以调用AddHttpMessageHandler,传入标头的类型。
  可以按处理程序应该执行的顺序注册多个处理程序。每个处理程序都会覆盖下一个处理程序,直到最终HttpClientHandler执行请求:services。AddTransientSecureRequestHandler();services。AddTransientRequestDataHandler();services。AddHttpClient(clientwithhandlers)Thishandlerisontheoutsideandcalledfirstduringtherequest,lastduringtheresponse。。AddHttpMessageHandlerSecureRequestHandler()Thishandlerisontheinside,closesttotherequestbeingsent。。AddHttpMessageHandlerRequestDataHandler();在出站请求中间件中使用DI
  当IHttpClientFactory创建新的委托处理程序时,它使用DI来完成处理程序的构造函数参数。IHttpClientFactory为每个处理程序创建单独的DI范围,当处理程序使用限定范围的服务时,这可能导致意外的行为。
  例如,请考虑下面的接口及其实现,它将任务表示为带有标识符OperationId的操作:publicinterfaceIOperationScoped{stringOperationId{}}publicclassOperationScoped:IOperationScoped{publicstringOperationId{}Guid。NewGuid()。ToString()〔4。。〕;}
  顾名思义,使用限定范围的生存期向DI注册IOperationScoped:publicvoidConfigureServices(IServiceCollectionservices){services。AddDbContextTodoContext(optionsoptions。UseInMemoryDatabase(TodoItems));services。AddHttpContextAccessor();services。AddHttpClientTodoClient((sp,httpClient){varhttpRequestsp。GetRequiredServiceIHttpContextAccessor()。HttpContext。RForsamplepurposes,assumeTodoClientisusedinthecontextofanincomingrequest。httpClient。BaseAddressnewUri(UriHelper。BuildAbsolute(httpRequest。Scheme,httpRequest。Host,httpRequest。PathBase));httpClient。TimeoutTimeSpan。FromSeconds(5);});services。AddScopedIOperationScoped,OperationScoped();services。AddTransientOperationHandler();services。AddTransientOperationResponseHandler();services。AddHttpClient(Operation)。AddHttpMessageHandlerOperationHandler()。AddHttpMessageHandlerOperationResponseHandler()。SetHandlerLifetime(TimeSpan。FromSeconds(5));services。AddControllers();services。AddRazorPages();}
  以下委托处理程序消耗并使用IOperationScoped来设置传出请求的XOPERATIONID标头:publicclassOperationHandler:DelegatingHandler{privatereadonlyIOperationScopedoperationSpublicOperationHandler(IOperationScopedoperationScoped){operationServiceoperationS}protectedasyncoverrideTaskHttpResponseMessageSendAsync(HttpRequestMessagerequest,CancellationTokencancellationToken){request。Headers。Add(XOPERATIONID,operationService。OperationId);returnawaitbase。SendAsync(request,cancellationToken);}}
  在HttpRequestsSample下载〕中,导航到Operation并刷新页面。每个请求的请求范围值发生更改,但处理程序范围值仅每5秒钟更改一次。
  处理程序可依赖于任何作用域的服务。处理程序依赖的服务会在处置处理程序时得到处置。
  使用以下方法之一将每个请求状态与消息处理程序共享:使用HttpRequestMessage。Properties将数据传递到处理程序中。使用IHttpContextAccessor访问当前请求。创建自定义AsyncLocal存储对象以传递数据。使用基于Polly的处理程序
  IHttpClientFactory与第三方库Polly集成。Polly是适用于。NET的全面恢复和临时故障处理库。开发人员通过它可以表达策略,例如以流畅且线程安全的方式处理重试、断路器、超时、Bulkhead隔离和回退。
  提供了扩展方法,以实现将Polly策略用于配置的HttpClient实例。Polly扩展支持将基于Polly的处理程序添加到客户端。Polly需要Microsoft。Extensions。Http。PollyNuGet包。处理临时故障
  错误通常在暂时执行外部HTTP调用时发生。AddTransientHttpErrorPolicy允许定义一个策略来处理暂时性错误。使用AddTransientHttpErrorPolicy配置的策略处理以下响应:HttpRequestExceptionHTTP5xxHTTP408
  AddTransientHttpErrorPolicy提供对PolicyBuilder对象的访问权限,该对象配置为处理表示可能的临时故障的错误:publicvoidConfigureServices(IServiceCollectionservices){services。AddHttpClientUnreliableEndpointCallerService()。AddTransientHttpErrorPolicy(pp。WaitAndRetryAsync(3,TimeSpan。FromMilliseconds(600)));Remainingcodedeletedforbrevity。
  上述代码中定义了WaitAndRetryAsync策略。请求失败后最多可以重试三次,每次尝试间隔600ms。动态选择策略
  提供了扩展方法来添加基于Polly的处理程序,例如AddPolicyHandler。以下AddPolicyHandler重载检查请求以确定要应用的策略:vartimeoutPolicy。TimeoutAsyncHttpResponseMessage(TimeSpan。FromSeconds(10));varlongTimeoutPolicy。TimeoutAsyncHttpResponseMessage(TimeSpan。FromSeconds(30));services。AddHttpClient(conditionalpolicy)Runsomecodetoselectapolicybasedontherequest。AddPolicyHandler(requestrequest。MethodHttpMethod。Get?timeout:longTimeout);
  在上述代码中,如果出站请求为HTTPGET,则应用10秒超时。其他所有HTTP方法应用30秒超时。添加多个Polly处理程序
  这对嵌套Polly策略很常见:services。AddHttpClient(multiplepolicies)。AddTransientHttpErrorPolicy(pp。RetryAsync(3))。AddTransientHttpErrorPolicy(pp。CircuitBreakerAsync(5,TimeSpan。FromSeconds(30)));
  在上面的示例中:添加了两个处理程序。第一个处理程序使用AddTransientHttpErrorPolicy添加重试策略。若请求失败,最多可重试三次。第二个AddTransientHttpErrorPolicy调用添加断路器策略。如果尝试连续失败了5次,则会阻止后续外部请求30秒。断路器策略处于监控状态。通过此客户端进行的所有调用都共享同样的线路状态。从Polly注册表添加策略
  管理常用策略的一种方法是一次性定义它们并使用PolicyRegistry注册它们。
  在以下代码中:添加了常规和长策略。AddPolicyHandlerFromRegistry从注册表中添加常规和长策略。
  CpublicvoidConfigureServices(IServiceCollectionservices){vartimeoutPolicy。TimeoutAsyncHttpResponseMessage(TimeSpan。FromSeconds(10));varlongTimeoutPolicy。TimeoutAsyncHttpResponseMessage(TimeSpan。FromSeconds(30));varregistryservices。AddPolicyRegistry();registry。Add(regular,timeout);registry。Add(long,longTimeout);services。AddHttpClient(regularTimeoutHandler)。AddPolicyHandlerFromRegistry(regular);services。AddHttpClient(longTimeoutHandler)。AddPolicyHandlerFromRegistry(long);Remainingcodedeletedforbrevity。
  有关IHttpClientFactory和Polly集成的详细信息,请参阅PollyWiki。HttpClient和生存期管理
  每次对IHttpClientFactory调用CreateClient都会返回一个新HttpClient实例。每个命名客户端都创建一个HttpMessageHandler。工厂管理HttpMessageHandler实例的生存期。
  IHttpClientFactory将工厂创建的HttpMessageHandler实例汇集到池中,以减少资源消耗。新建HttpClient实例时,可能会重用池中的HttpMessageHandler实例(如果生存期尚未到期的话)。
  由于每个处理程序通常管理自己的基础HTTP连接,因此需要池化处理程序。创建超出必要数量的处理程序可能会导致连接延迟。部分处理程序还保持连接无期限地打开,这样可以防止处理程序对DNS(域名系统)更改作出反应。
  处理程序的默认生存期为两分钟。可在每个命名客户端上重写默认值:publicvoidConfigureServices(IServiceCollectionservices){services。AddHttpClient(extendedhandlerlifetime)。SetHandlerLifetime(TimeSpan。FromMinutes(5));Remainingcodedeletedforbrevity。
  HttpClient实例通常可视为无需处置的。NET对象。处置既取消传出请求,又保证在调用Dispose后无法使用给定的HttpClient实例。IHttpClientFactory跟踪和处置HttpClient实例使用的资源。
  保持各个HttpClient实例长时间处于活动状态是在IHttpClientFactory推出前使用的常见模式。迁移到IHttpClientFactory后,就无需再使用此模式。IHttpClientFactory的替代项
  通过在启用了DI的应用中使用IHttpClientFactory,可避免:通过共用HttpMessageHandler实例,解决资源耗尽问题。通过定期循环HttpMessageHandler实例,解决DNS过时问题。
  此外,还有其他方法使用生命周期长的SocketsHttpHandler实例来解决上述问题。在应用启动时创建SocketsHttpHandler的实例,并在应用的整个生命周期中使用它。根据DNS刷新时间,将PooledConnectionLifetime配置为适当的值。根据需要,使用newHttpClient(handler,disposeHandler:false)创建HttpClient实例。
  上述方法使用IHttpClientFactory解决问题的类似方式解决资源管理问题。SocketsHttpHandler在HttpClient实例之间共享连接。此共享可防止套接字耗尽。SocketsHttpHandler会根据PooledConnectionLifetime循环连接,避免出现DNS过时问题。Cookies
  共用HttpMessageHandler实例将导致共享CookieContainer对象。意外的CookieContainer对象共享通常会导致错误的代码。对于需要cookie的应用,请考虑执行以下任一操作:禁用自动cookie处理避免IHttpClientFactory
  调用ConfigurePrimaryHttpMessageHandler以禁用自动cookie处理:services。AddHttpClient(configureddisableautomaticcookies)。ConfigurePrimaryHttpMessageHandler((){returnnewHttpClientHandler(){UseCookiesfalse,};});Logging
  通过IHttpClientFactory创建的客户端记录所有请求的日志消息。在日志记录配置中启用合适的信息级别可以查看默认日志消息。仅在跟踪级别包含附加日志记录(例如请求标头的日志记录)。
  用于每个客户端的日志类别包含客户端名称。例如,名为MyNamedClient的客户端记录类别为System。Net。Http。HttpClient。MyNamedClient。LogicalHandler的消息。后缀为LogicalHandler的消息在请求处理程序管道外部发生。在请求时,在管道中的任何其他处理程序处理请求之前记录消息。在响应时,在任何其他管道处理程序接收响应之后记录消息。
  日志记录还在请求处理程序管道内部发生。在MyNamedClient示例中,这些消息的日志类别为System。Net。Http。HttpClient。MyNamedClient。ClientHandler。在请求时,在所有其他处理程序运行后,以及刚好要发出请求之前记录消息。在响应时,此日志记录包含响应在通过处理程序管道被传递回去之前的状态。
  在管道内外启用日志记录,可以检查其他管道处理程序做出的更改。这可能包含对请求标头的更改,或者对响应状态代码的更改。
  通过在日志类别中包含客户端名称,可以对特定的命名客户端筛选日志。配置HttpMessageHandler
  控制客户端使用的内部HttpMessageHandler的配置是有必要的。
  在添加命名客户端或类型化客户端时,会返回IHttpClientBuilder。ConfigurePrimaryHttpMessageHandler扩展方法可以用于定义委托。委托用于创建和配置客户端使用的主要HttpMessageHandler:publicvoidConfigureServices(IServiceCollectionservices){services。AddHttpClient(configuredinnerhandler)。ConfigurePrimaryHttpMessageHandler((){returnnewHttpClientHandler(){AllowAutoRedirectfalse,UseDefaultCredentialstrue};});Remainingcodedeletedforbrevity。在控制台应用中使用IHttpClientFactory
  在控制台中,将以下包引用添加到项目中:Microsoft。Extensions。HostingMicrosoft。Extensions。Http
  如下示例中:IHttpClientFactory已在泛型主机的服务容器中注册。MyService从服务创建客户端工厂实例,用于创建HttpClient。HttpClient用于检索网页。Main可创建作用域来执行服务的GetPage方法,并将网页内容的前500个字符写入控制台。usingSusingSystem。Net。HusingSystem。Threading。TusingMicrosoft。Extensions。DependencyIusingMicrosoft。Extensions。HusingMicrosoft。Extensions。LclassProgram{staticasyncTaskintMain(string〔〕args){varbuildernewHostBuilder()。ConfigureServices((hostContext,services){services。AddHttpClient();services。AddTransientIMyService,MyService();})。UseConsoleLifetime();varhostbuilder。Build();try{varmyServicehost。Services。GetRequiredServiceIMyService();varpageContentawaitmyService。GetPage();Console。WriteLine(pageContent。Substring(0,500));}catch(Exceptionex){varloggerhost。Services。GetRequiredServiceILoggerProgram();logger。LogError(ex,Anerroroccurred。);}return0;}publicinterfaceIMyService{TaskstringGetPage();}publicclassMyService:IMyService{privatereadonlyIHttpClientFactoryclientFpublicMyService(IHttpClientFactoryclientFactory){clientFactoryclientF}publicasyncTaskstringGetPage(){ContentfromBBCOne:Dr。Whowebsite(BBC)varrequestnewHttpRequestMessage(HttpMethod。Get,https:www。bbc。co。ukprogrammesb006q2x0);varclientclientFactory。CreateClient();varresponseawaitclient。SendAsync(request);if(response。IsSuccessStatusCode){returnawaitresponse。Content。ReadAsStringAsync();}else{return34;StatusCode:{response。StatusCode};}}}}标头传播中间件
  标头传播是一个ASP。NETCore中间件,可将HTTP标头从传入请求传播到传出HTTP客户端请求。使用标头传播:引用Microsoft。AspNetCore。HeaderPropagation包。在Startup中配置中间件和HttpClient:publicvoidConfigureServices(IServiceCollectionservices){services。AddControllers();services。AddHttpClient(MyForwardingClient)。AddHeaderPropagation();services。AddHeaderPropagation(options{options。Headers。Add(XTraceId);});}publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){if(env。IsDevelopment()){app。UseDeveloperExceptionPage();}app。UseHttpsRedirection();app。UseHeaderPropagation();app。UseRouting();app。UseAuthorization();app。UseEndpoints(endpoints{endpoints。MapControllers();});}客户端在出站请求中包含配置的标头:varclientclientFactory。CreateClient(MyForwardingClient);varresponseclient。GetAsync(。。。);
投诉 评论 转载

被元宇宙再次带火的VRAR产业,是风口还是泡沫?中国商报(见习记者赵熠如)在近期元宇宙概念火爆的同时,作为其技术支撑的VR(虚拟现实)、AR(增强现实)再次进入人们的视野。科技巨头纷纷入局、资本市场狂热追捧的当下,VRAR产……蒸发4万亿!十大互联网公司股价雪崩,中国经济的巨轮开始转向今年的股市行情起伏跌宕,令人堪忧,尤其是各种教育培训机构,各种跌,真是做什么都不容易啊。奋斗了几十年,一下子凉了。老百姓有句俗语,辛辛苦苦几十年,一阵大风撸了杆。但是对于……学校设备维修(三)有一批班级多媒体,共12套,每套包含壁挂一体机、希沃触屏70寸电视。已经三年了。今年开学起就不断出现状况。自动关机、自动重启。特别严重的,使用不了,实在没办法,只有用台式……中国院士说的没错,北邮取得6G新进展,美国6G只能陪跑在当前的全球通信行业,5G是最主流的技术,各个国家都在积极地建设本国的5G网络。而之前的4G,虽然还没有彻底被淘汰,但是要不了几年,就会走向落幕,这是时代向前发展产生的必然结果……有人说物体的运动速度不能超过光速,那么宇宙的膨胀速度为什么大光子的运动速度,是具体物质的最大速度,虽然光与一般物体的运动形式不一样,但它脱离不了光子的来源物质电子是具体的物质的跃迁。而膨胀速度,是宇宙最初的总能量所给予。在迈克斯韦……用惯安卓系统后,再次换回iOS是种什么体验?说到心坎了之前一直用的就是安卓手机,小米、华为、一加都用过,甚至华为推出鸿蒙之后,还用了一段时间的鸿蒙系统,主要是因为工作原因,一些软件苹果手机下不了,但是感觉也是非常不错的。但是……京东回应快手切断外链杨国福冲击麻辣烫第一股【亿邦动力】京东回应快手切断外链:此次调整几乎没有影响今日,京东方面就快手切断外链一事做出回应:京东和快手电商直播更多是基于供应链层面的合作,此次调整对京东几乎没有影响。……中国5G商用两周年应用规模化挑战待解本报记者谭伦北京报道9月27日,2021年中国信息通信博览会(以下简称通信展)在北京召开。这是自2019年通信展上三大运营商官宣启动5G商用后,中国5G产业迎来的两周年标……在ASP。NETCore中使用IHttpClientFact可以注册IHttpClientFactory并将其用于配置和创建应用中的HttpClient实例。IHttpClientFactory的优势如下:提供一个中心位置,用于命名和配……分析师爆猛料iPhone15或采用USBC接口让苹果回归主流,放弃Lightning口,可能吗?5月11日,分析师郭明錤表示,iPhone15可能是第一款采用USBC端口代替Lightning的iPhone,在硬件上……DID,解锁元宇宙近日,在Medium上,人工智能行业编辑JonRadoff发表了关于元宇宙(Metaverse)未来9大趋势的看法,分别从互联网、代码、区块链、机器智能化等九大方面解释了元宇宙……小米12Pro5G新机概念渲染图曝光,小米11跌至发烧价创感预计下周到货的小米12系列智能手机将包括入门级LiteLiteZoom和紧凑但功能强大的12X型号。不过,大家最担心的还是旗舰小米12Pro5G。基于之前的许多泄密和披露,荷兰……
刘晓春数据治理是科技向善的源头为什么你的手机越来越不耐用了?超级重要的Java知识点详解集合框架有没有可能有一个比我们地球大一万倍的地球,然后上面的人类也比HomePod终于支持空间音频和无损播放,效果震撼如果当年是任正非管理联想和计算所会有怎样的惊喜?我们至今仍未找到一位互联网退休员工今天左晖去世了,不由得想起了乔布斯你觉得荣耀V20可以用多久?花1999买了款红米K40,回来对比IQOOZ5后这下纠结了逐梦冰雪向未来!安徽科技元素助力北京冬奥会网络自制食品有这些安全隐患

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利