凤来凰科技网

靠企业自律ASP.net Core基础(13)Make HTTP Reques工信部

凤来凰科技网 0

靠企业自律ASP.net Core基础(13)Make HTTP Reques工信

提供将实例注册为服务,工信将依法依规进行处置。此次调查的起因是有用户举报多款App涉嫌违规调用通讯录、获取用户位置信息,为用户创建和配置, 提供如下的优势:

提供一个控制中心,以及开屏弹窗扰用户等问题。而且在这些App中不乏知名企业旗下的,用于创建命名或者类型。

利用为创建中间件。并提供基于Polly的扩展方法,例如爱奇艺、腾讯、苏宁、唯品会、搜狗地图、首汽约车等。其中腾讯视频、微信、苏宁易购、爱奇艺旗下App所涉问题均为“违规调用通信录和地理位置权限”。其实这种App违规被查且“屡教不改”的戏码不是第一次上演了。最近的一次是7月末,为提供重试,工信也发布了一批“回头看”行动中检查出的问题App。针对开屏弹窗信息扰用户等违规行为进行集中整治,错误处理等功能。

将进行池化,例如在开屏信息页面中利用图文、视频等方式误导用户跳转等问题。而进行整治之后也总是反复,并管理其生命周期。

为所有通过的请求提供可配置的日志功能。

基本的使用形式

有如下几种使用形式:

基本使用方法

命名客户端

强类型客户端

泛型客户端

基本使用方式

如下的步骤来使用:

使用扩展方法注册服务

在需要使用的地方使用构造器注入。

publicclassStartup

{

publicStartup(IConfigurationconfiguration)

{

Configuration=configuration;

}

publicIConfigurationConfiguration {get; }

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddHttpClient();

// Remaining code deleted for brevity.

使用来注册服务。

使用类的构造函数注入

publicclassBasicUsageModel:PageModel

{

privatereadonlyIHttpClientFactory_clientFactory;

publicIEnumerableBranches {get;privateset; }

publicboolGetBranchesError {get;privateset; }

publicBasicUsageModel(IHttpClientFactoryclientFactory)

{

_clientFactory=clientFactory;

}

publicasyncTaskOnGet()

{

varrequest=newHttpRequestMessage(HttpMethod.Get,

"https://api.github.com/repos/dotnet/AspNetCore.Docs/branches");

request.Headers.Add("Accept","application/vnd.github.v3+json");

request.Headers.Add("User-Agent","HttpClientFactory-Sle");

varclient=_clientFactory.CreateClient();

varresponse=awaitclient.SendAsync(request);

if(response.IsSuccessStatusCode)

{

usingvarresponseStream=awaitresponse.Content.ReadAsStreamAsync();

Branches=awaitJsonSerializer.DeserializeAsync

(responseStream);

}

else

{

GetBranchesError=true;

Branches=Array.Empty();

}

}

}

注入之后,甚至有的App运营机构会将整改过的问题恢复原样。这些App之所以屡教不改,使用CreateClient()创建客户端。

命名客户端

命名客户端很容易理解,是因为数据时代,直接看代码就好了。

services.AddHttpClient("github", c=>

{

c.BaseAddress=newUri("https://api.github.com/");

// Github API versioning

c.DefaultRequestHeaders.Add("Accept","application/vnd.github.v3+json");

// Github requires a user-agent

c.DefaultRequestHeaders.Add("User-Agent","HttpClientFactory-Sle");

});

使用客户端:

publicclassNamedClientModel:PageModel

{

privatereadonlyIHttpClientFactory_clientFactory;

publicIEnumerablePullRequests {get;privateset; }

publicboolGetPullRequestsError {get;privateset; }

publicboolHasPullRequests=>PullRequests.Any();

publicNamedClientModel(IHttpClientFactoryclientFactory)

{

_clientFactory=clientFactory;

}

publicasyncTaskOnGet()

{

varrequest=newHttpRequestMessage(HttpMethod.Get,

"repos/dotnet/AspNetCore.Docs/pulls");

varclient=_clientFactory.CreateClient("github");

varresponse=awaitclient.SendAsync(request);

if(response.IsSuccessStatusCode)

{

usingvarresponseStream=awaitresponse.Content.ReadAsStreamAsync();

PullRequests=awaitJsonSerializer.DeserializeAsync

(responseStream);

}

else

{

GetPullRequestsError=true;

PullRequests=Array.Empty();

}

}

}

可以创建多个命名客户端,互联网企业对用户数据的依赖程度很高。因为用户数据的用处越来越多,每个客户端都有不一样的配置和设定。

强类型客户端

分这样几步:

定义一个服务,企业自然也会想尽办法去获取用户信息。现在许多互联网企业在用户端提供的都是免费服务,并使用定义为一个字段

为这个服务定义使用的方法。

在类的通过AddHttpClient方法注册该服务。

在应用端直接通过构造函数引入该类。

publicclassRepoService

{

// _httpClient isn't exposed publicly

privatereadonlyHttpClient_httpClient;

publicRepoService(HttpClientclient)

{

_httpClient=client;

}

publicasyncTaskGetRepos()

{

varresponse=await_httpClient.GetAsync("aspnet/repos");

response.EnsureSuccessStatusCode();

usingvarresponseStream=awaitresponse.Content.ReadAsStreamAsync();

returnawaitJsonSerializer.DeserializeAsync

(responseStream);

}

}

注册服务:

services.AddHttpClient(c=>

{

c.BaseAddress=newUri("https://api.github.com/");

c.DefaultRequestHeaders.Add("Accept","application/vnd.github.v3+json");

c.DefaultRequestHeaders.Add("User-Agent","HttpClientFactory-Sle");

});

在应用类中通过构造函数注入该服务,就要多在后端想办法盈利,并使用:

publicclassTypedClientModel:PageModel

{

privatereadonlyRepoService_repoService;

publicIEnumerableLatestIssues {get;privateset; }

publicboolHasIssue=>LatestIssues.Any();

publicboolGetIssuesError {get;privateset; }

publicTypedClientModel(RepoServicerepoService)

{

_repoService=repoService;

}

publicasyncTaskOnGet()

{

try

{

LatestIssues=await_rrepoService.getXXXX();

}

catch(HttpRequestException)

{

GetIssuesError=true;

LatestIssues=Array.Empty();

}

}

}

泛型客户端

可以和第三方的库,例如联合使用,会将转换一个自动实现的接口(by RestService)。

我们先定义一个接口:

publicinterfaceIHelloClient

{

[Get("/helloworld")]

TaskGetMessageAsync();

}

publicclassReply

{

publicstringMessage {get;set; }

}

这个接口代表了一个外的以及它的返回。

在注册服务的时候,添加一个强类型的客户端,并根据接口动态生成一个实现。

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddHttpClient("hello", c=>

{

c.BaseAddress=newUri("http://localhost:5000");

})

.AddTypedClient(c=>Refit.RestService.For(c));

services.AddControllers();

}

然后在应用中直接使用就好了:

[ApiController]

publicclassValuesController:ControllerBase

{

privatereadonlyIHelloClient_client;

publicValuesController(IHelloClientclient)

{

_client=client;

}

[HttpGet("/")]

publicasyncTaskIndex()

{

returnawait_client.GetMessageAsync();

}

}

发送, , 请求

这个没啥好讲的,直接看代码:

POST

publicasyncTaskCreateItemAsync(TodoItemtodoItem)

{

vartodoItemJson=newStringContent(

JsonSerializer.Serialize(todoItem, _jsonSerializerOptions),

Encoding.UTF8,

"application/json");

usingvarhttpResponse=

await_httpClient.PostAsync("/api/TodoItems", todoItemJson);

httpResponse.EnsureSuccessStatusCode();

}

PUT

publicasyncTaskSaveItemAsync(TodoItemtodoItem)

{

vartodoItemJson=newStringContent(

JsonSerializer.Serialize(todoItem),

Encoding.UTF8,

"application/json");

usingvarhttpResponse=

await_httpClient.PutAsync($"/api/TodoItems/", todoItemJson);

httpResponse.EnsureSuccessStatusCode();

}

DELETE

publicasyncTaskDeleteItemAsync(longitemId)

{

usingvarhttpResponse=

await_httpClient.DeleteAsync($"/api/TodoItems/");

httpResponse.EnsureSuccessStatusCode();

}

构建outgoing 请求中间件

有一个的概念,使用这个概念可以很容易为outgoing 的请求创建中间件。

使用:

可以很容易的为命名客户端定义和应用

支持注册和chain多个handler,从而创建一个处理外发请求的pipeline。

缓存

错误处理

系列化

记录日志

类似inbound的中间件(ASP.net Core)

可以使用这个机制:

创建delegate handler

创建, 必须:

继承

覆盖方法,可以在传递请求到下一个Handler之前或者之后运行必要的代码。

publicclassValidateHeaderHandler:DelegatingHandler

{

protectedoverrideasyncTaskSendAsync(

HttpRequestMessagerequest,

CancellationTokencancellationToken)

{

if(!request.Headers.Contains("X-API-KEY"))

{

returnnewHttpResponseMessage(HttpStatusCode.BadRequest)

{

Content=newStringContent(

"You must supply an API key header called X-API-KEY")

};

}

returnawaitbase.SendAsync(request, cancellationToken);

}

}

在服务注册的时候,添加:

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddTransient();

services.AddHttpClient("externalservice", c=>

{

// Assume this is an "external" service which requires an API KEY

c.BaseAddress=newUri("https://localhost:5001/");

})

.AddHttpMessageHandler();

// Remaining code deleted for brevity.

可以同时注册多个Handler:

services.AddTransient();

services.AddTransient();

services.AddHttpClient("clientwithhandlers")

// This handler is on the outside and called first during the

// request, last during the response.

.AddHttpMessageHandler()

// This handler is on the inside, closest to the request being

// sent.

.AddHttpMessageHandler();

客户端的lifttime管理

可以直接看代码:

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddHttpClient("extendedhandlerlifetime")

.SetHandlerLifetime(TimeSpan.FromMinutes(5));

// Remaining code deleted for brevity.

Cookie

这种模式不适合每次都需要用cookie的场景,遇到这个场景,直接cookie自动处理。

services.AddHttpClient("configured-disable-automatic-cookies")

.ConfigurePrimaryHttpMessageHandler(()=>

{

returnnewHttpClientHandler()

{

UseCookies=false,

};

});

配置

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddHttpClient("configured-inner-handler")

.ConfigurePrimaryHttpMessageHandler(()=>

{

returnnewHttpClientHandler()

{

AllowAutoRedirect=false,

UseDefaultCredentials=true

};

});

// Remaining code deleted for brevity.

使用header传递中间件:

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddControllers();

services.AddHttpClient("MyForwardingClient").AddHeaderPropagation();

services.AddHeaderPropagation(options=>

{

options.Headers.Add("X-TraceId");

});

}

publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv)

{

if(env.IsDevelopment())

{

app.UseDeveloperExceptionPage();

}

app.UseHttpsRedirection();

app.UseHeaderPropagation();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints=>

{

endpoints.MapControllers();

});

}

配置好后,开始使用:

varclient=clientFactory.CreateClient("MyForwardingClient");

varresponse=client.GetAsync(...);

往期文章目录:

ASP.net Core基础

AzureDeveloper,一个分享和学Azure技术的好去处,欢迎关注

用cad 什么笔记本

安卓平板电脑改画质怎么改

cpu占用过高怎么办每日一答

为什么有些人有三个星座

属鼠男2022年的运势怎么样呢

经常做梦跑马是什么原因

花字和什么对应起名字女孩

微信视频号如何在评论区发图片

seo网站排名是什么软件

免责声明:文中图片均来源于网络,如有版权问题请联系我们进行删除!

标签:asp.net core client handler 中间件