ASP.NET Core扩展库之Http通用扩展库的使用详解

本文将介绍Xfrogcn.AspNetCore.Extensions扩展库对于Http相关的其他功能扩展,这些功能旨在处理一些常见需求, 包括请求缓冲、请求头传递、请求头日志范围、针对HttpClient与HttpRequestMessage、HttpResponseMessage的扩展方法。

一、开启服务端请求缓冲

ASP.NET Core 中请求体是不能多次读取的,由于在MVC中,框架已经读取过请求体,如果你在控制器中再次读取,将会引发异常,如下示例:

    [ApiController]
    [Route("[controller]")]
    public class TestController : ControllerBase
    {

        public TestController()
        {

        }

        [HttpPost]
        public async Task<WeatherForecast> Save([FromBody]WeatherForecast enttiy)
        {
            using (StreamReader reader = new StreamReader(Request.Body))
            {
                Request.Body.Position = 0;
                string response = await reader.ReadToEndAsync();
            }
            return enttiy;
        }
    }

当通过Post请求/test接口时,语句 Request.Body.Position 将触发异常:

System.NotSupportedException: Specified method is not supported.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.set_Position(Int64 value)

当然,实际中可能不会像示例这样处理请求,但在业务需求中,的确可能会有多次读取请求体的情况出现。

通过开启请求缓冲可以解决多次读取请求体的问题,Xfrogcn.AspNetCore.Extensions扩展库提供了EnableBufferingAttribute特性用于开启请求缓冲,你可以将此特性用于控制器或者Action方法。

以上示例,只需在Save方法上添加EnableBuffering特性:

    [HttpPost]
    [EnableBuffering]
    public async Task<WeatherForecast> Save([FromBody]WeatherForecast enttiy)
    {
        ....
    }

二、请求头传递

微服务架构下,通常我们使用请求头来实现请求的链路跟踪以及日志与请求的关联,例如,通过x-request-id,在日志系统中可以直接查看某一个请求在所有服务中的相关日志。

扩展库通过拦截HttpClient请求管道,可实现对指定请求头的自动传递。默认配置下,扩展库会自动传递以"x-"开始的请求头,如果你需要传递其他的请求头,可通过配置中的TrackingHeaders来添加。

    IServiceCollection services = new ServiceCollection()
        .AddExtensions(null, config =>
        {
            // 自动传递以my-为前缀的请求头
            config.TrackingHeaders.Add("my-*");
        });

三、请求头日志的记录

.NET Core日志框架中,实现了日志范围的概念,通过日志范围,可以让日志系统记录当前上下文的信息,例如,ASP.NET Core MVC中,日志范围包含ActionContext相关信息,故可以在一个请求的所有日志中都可自动记录Action的相关信息。

扩展库可以将配置的请求头加入请求的日志范围,例如,默认配置下,扩展库会将x-request-id加入到请求的日志范围,所以在单一请求中的所有日志,都可自动携带x-request-id信息,以此实现跨服务的日志关联。要包含其他的请求头,可以通过配置中的HttpHeaders来设置:

    IServiceCollection services = new ServiceCollection()
        .AddExtensions(null, config =>
        {
            // 将my-id请求头包含到日志范围
            config.HttpHeaders.Add("my-id");
        });

注意: 默认的控制台日志、文件日志不会保存日志范围的相关信息,你可以使用json格式的控制台日志或文件日志,在此格式下将保存日志范围中的数据。

    IServiceCollection services = new ServiceCollection()
        .AddExtensions(null, config =>
        {
            config.ConsoleJsonLog = true;
        });

四、Http消息上的扩展方法

扩展库在HttpRequestMessage上提供了GetObjectAsync、WriteObjectAsync扩展方法,以便于对请求消息的读写。 在HttpResponseMessage上提供了GetObjectAsync、WriteObjectAsync扩展方法,以便于对应答消息的读写。这些方法都采用json格式。

示例:

    public class WeatherForecast
    {
        public DateTime Date { get; set; }

        public int TemperatureC { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

        public string Summary { get; set; }
    }
    static async Task Main(string[] args)
    {
        IServiceCollection services = new ServiceCollection()
            .AddExtensions(null, config =>
            {
            });

        IServiceProvider serviceProvider = services.BuildServiceProvider();

        IHttpClientFactory factory = serviceProvider.GetRequiredService<IHttpClientFactory>();
        HttpClient client = factory.CreateClient();

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:5000/test");

        // 写入请求对象
        await request.WriteObjectAsync(new WeatherForecast()
        {
            Date = DateTime.Now
        });
        request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

        // 读取请求对象
        var entity = await request.GetObjectAsync<WeatherForecast>();

        HttpResponseMessage response = await client.SendAsync(request);

        // 读取应答对象
        entity = await response.GetObjectAsync<WeatherForecast>();

        Console.ReadLine();
    }

五、HttpClient上的扩展方法

为了更方便快捷地使用HttpClient,扩展库在HttpClient上增加了多个扩展方法:

  • PostAsync<TResponse>: 发送对象到服务端,并获取指定类型的应答
  • PostAsync: 发送对象到服务端,并获取应答字符串
  • GetAsync<TResponse>: 发送Get请求,并获取TResponse类型的应答
  • GetAsync: 发送Get请求,并获取String类型的应答
  • SubmitFormAsync<TResponse>: 向服务器提交表单数据,并获取TResponse类型的应答
  • SubmitFormAsync: 向服务器提交表单数据,并获取String类型的应答
  • UploadFileAsync<TResponse>: 上次本地文件
  • UploadStreamAsync<TResponse>: 上传流数据到服务器

有关这些扩展方法的详细说明,可参考文档 GitHub Gitee

Xfrogcn.AspNetCore.Extensions地址:GitHub Gitee

以上就是ASP.NET Core扩展库之Http通用扩展库的使用详解的详细内容,更多关于ASP.NET Core扩展库之Http通用扩展库的资料请关注我们其它相关文章!

(0)

相关推荐

  • .NET CORE HttpClient的使用方法

    前言 自从HttpClient诞生依赖,它的使用方式一直备受争议,framework版本时代产生过相当多经典的错误使用案例,包括Tcp链接耗尽.DNS更改无感知等问题.有兴趣的同学自行查找研究.在.NETCORE版本中,提供了IHttpClientFactory用来创建HttpClient以解决之前的种种问题.那么我们一起看一下它的用法. 使用方式 基本用法. 直接注入IHttpClientFactory 命名客户端.注入IHttpClientFactory并带有名称,适用于需要特定的客户端配置

  • .Net Core下HTTP请求IHttpClientFactory示例详解

    使用方式 IHttpClientFactory有四种模式: 基本用法 命名客户端 类型化客户端 生成的客户端 基本用法 在 Startup.ConfigureServices 方法中,通过在 IServiceCollection 上调用 AddHttpClient 扩展方法可以注册 IHttpClientFactory services.AddHttpClient(); 注册之后可以像依赖注入DI似得在类中通过构造函数注入形式使用,伪代码: class A { private readonly

  • 在ASP.NET Core中应用HttpClient获取数据和内容

    在本文中,我们将学习如何在ASP.NET Core中集成和使用HttpClient.在学习不同HttpClient功能的同时使用Web API的资源.如何从Web API获取数据,以及如何直接使用HttpRequestMessage类来实现这些功能.在以后的文章中,我们将学习如何发送POST.PUT和DELETE请求,以及如何使用HttpClient发送PATCH请求. 要下载源代码,可以访问https://github.com/CodeMazeBlog/httpclient-aspnetcor

  • 如何在 .NET 中使用 Flurl 高效处理Http请求

    简介 官方介绍,Flurl是一个现代的,流利的,支持异步的,可测试的,可移植的,URL增强和Http客户端组件. Url构建 现在有一个登录的接口,地址如下: https://www.some-api.com/login?name=Lee&pwd=123456 我们在处理这个地址的时候,会拼接 login,然后拼接?号,然后拼接参数,中间还要拼接& 得到最终的地址. 使用 Flurl 构建,首先需要通过 Nuget 安装 Flurl 组件. var url = "http://w

  • ASP.NET Core扩展库之Http日志的使用详解

    最佳实践都告诉我们不要记录请求的详细日志,因为这有安全问题,但在实际开发中,请求的详细内容对于快速定位问题却是非常重要的,有时也是系统的强力证据.Xfrogcn.AspNetCore.Extensions扩展库提供了服务端和客户端的详细日志功能,通过配置可以开启. 服务端日志通过请求中间件来完成,中间件会以Trace级别记录请求和应答详情,以Debug级别记录请求耗时.服务的请求日志的名称为ServerRequest.Logger 要开启服务端详情日志,只需将扩展库配置中的ServerReque

  • .NET Core使用HttpClient进行表单提交时遇到的问题

    问题# 在开发微信支付的小微商户进件接口时,需要通过表单来上传身份证图片等数据.在微信支付接口文档也说明了,需要使用 multipart/form-data 的方式发送请求..NET 提供了 MultipartFormDataContent 类型,帮助我们构建表单请求,故有以下代码: var form = new MultipartFormDataContent() { {new StringContent("Value"),"Name}, {new ByteArrayCon

  • 在ASP.NET Core5.0中访问HttpContext的方法步骤

    ASP.NET Core 应用通过 IHttpContextAccessor 接口及其默认实现 HttpContextAccessor 访问 HttpContext. 只有在需要访问服务内的 HttpContext 时,才有必要使用 IHttpContextAccessor. 通过 Razor Pages 使用 HttpContext Razor Pages PageModel 公开 HttpContext 属性: public class AboutModel : PageModel { pu

  • 如何在ASP.NET Core中使用HttpClientFactory

    ASP.Net Core 是一个开源的,跨平台的,轻量级模块化框架,可用它来构建高性能的Web程序,这篇文章我们将会讨论如何在 ASP.Net Core 中使用 HttpClientFactory. 为什么要使用 HttpClientFactory 可以用 HttpClientFactory 来集中化管理 HttpClient,工厂提供了对 HttpClient 的创建,配置和调度,值得一提的是:HttpClient 一直都是 Http 请求业务方面的一等公民. HttpClient 虽好,但它

  • ASP.NET Core中的Http缓存使用

    Http响应缓存可减少客户端或代理对web服务器发出的请求数.响应缓存还减少了web服务器生成响应所需的工作量.响应缓存由Http请求中的header控制. 而ASP.NET Core对其都有相应的实现,并不需要了解里面的工作细节,即可对其进行良好的控制. 了解Http缓存 Http协议中定义了许多缓存,但总体可以分为强缓存和协商缓存两类. 强缓存 强缓存是指缓存命中时,客户端不会向服务器发请求,浏览器F12能看到响应状态码为200,size为from cache,它的实现有以下几种方式: Ex

  • 在ASP.NET Core中用HttpClient发送POST, PUT和DELETE请求

    在上一篇文章中,我们已经学习了如何在ASP.NET Core中使用HttpClient从Web API获取数据.此外,我们还学习了如何使用GetAsync方法和HttpRequestMessage类发送GET请求.在本文中,我们将学习如何在ASP.NET Core中使用HttpClient发送POST.PUT和DELETE请求,并使用PostAsync.PutAsync.DeleteAsync和HttpRequestMessage类创建请求. 在ASP.NET Core中使用HttpClient

  • .net Core 使用IHttpClientFactory请求实现

    导读:本文已添加在 晨曦微服务之旅 ,现在自己在尝试微服务架构,一边学边做项目快速的进入状态.当然在学习的过程中会将自己学到的知识进行分享. 一.为什么不用HttpClient 1.HttPClient使用完之后不会立即关闭开启网络连接时会占用底层socket资源,但在HttpClient调用其本身的Dispose方法时,并不能立刻释放该资源 2.如果频繁的使用HttpClient,频繁的打开链接,关闭链接消耗就会很大. 二.解决方案 1.我们可以延长HttpClient的生命周期,比如对其建一

随机推荐