首页 > 编程语言 >C# HttpClient 的使用

C# HttpClient 的使用

时间:2023-03-14 17:56:25浏览次数:54  
标签:logBuilder C# AppendLine request responseMessage 使用 new LoggingHandler HttpClien

介绍个 HTTP Client 中常用于记录请求以及响应的中间建:System.Net.Http.DelegatingHandler 文档 ,不废话直接看代码

声明:全篇基于 .NET 7 编写


点击查看代码
public sealed class LoggingHandler : DelegatingHandler
{
    public LoggingHandler() : base()
    {
    }

    public LoggingHandler(HttpMessageHandler innerHandler) : base(innerHandler)
    {

    }
    /// <summary>
    /// 同步请求拦截器
    /// </summary>
    /// <param name="request"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        StringBuilder logBuilder = new(Environment.NewLine);
        Uri? uri = request.RequestUri;
        logBuilder.AppendLine($"\t== request uri: {uri} at {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}");
        logBuilder.AppendLine($"\t=- request method: {request.Method}");
        logBuilder.AppendLine($"\t=- request headers: {request.Headers.IObjectToJson()}");
        // 仅记录request.Content 是StringContent 的请求参数
        string requestContent = "";
        if (request.Content.GetType() == typeof(StringContent))
        {
            requestContent = request.Content.ReadAsStringAsync().Result;
        }
        logBuilder.AppendLine($"\t=@ request body: {requestContent}");
        HttpResponseMessage responseMessage = base.Send(request, cancellationToken);
        logBuilder.AppendLine($"\t=+ response headers: {responseMessage.Headers.IObjectToJson()}");
        if (!responseMessage.IsSuccessStatusCode)
        {
            string responseString = $"异常:{responseMessage.StatusCode}";
            // 非空时,写入响应异常信息
            logBuilder.Append($"\t=~ response error result: {responseString}");
        }
        // 日志记录,可替换为其他日志记录方式
        Log4Helper.WriteApiRequest(logBuilder.ToString(), callerMemberName);
        return responseMessage;
    }
    /// <summary>
    /// 异步请求拦截器
    /// </summary>
    /// <param name="request"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        StringBuilder logBuilder = new(Environment.NewLine);
        Uri? uri = request.RequestUri;
        logBuilder.AppendLine($"\t== async request uri: {uri} at {DateTime.Now:G}");
        logBuilder.AppendLine($"\t=- async request headers: {request.Headers.IObjectToJson()}");
        // 非json 请求,不记录请求 body
        string requestContent = "";
        if (request.Content?.GetType() == typeof(StringContent))
        {
            requestContent = request.Content.ReadAsStringAsync().Result;
        }

        logBuilder.AppendLine($"\t=@ request body: {requestContent}");
        // 添加 .ConfigureAwait(false) 避免同步线程上下文
        HttpResponseMessage responseMessage = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

        logBuilder.AppendLine($"\t=+ async response headers: {responseMessage.Headers.IObjectToJson()}");
        if (!responseMessage.IsSuccessStatusCode)
        {
            string responseString = $"异常:{responseMessage.StatusCode}";
            // 非空时,写入响应异常信息
            logBuilder.Append($"\t=~ response error result: {responseString}");
        }

        Log4Helper.WriteApiRequest(logBuilder.ToString());
        return responseMessage;
    }
}

示例中 LoggingHandler 继承自 System.Net.Http.DelegatingHandler

从上往下看,可以看到构造函数包含一个无参构造函数,以及一个有 HttpMessageHandler 的 构造函数,
在发送请求的顺序上来看,通常情况下 LoggingHandler 是作为最终的handler使用,
所以需要将内部handler传入,

使用(此处使用 直接 new 一个 新的HttpClient 实际情况按需处理):

点击查看代码
public sealed class HttpHelper
{
    private static readonly HttpMessageHandler handler = new HttpClientHandler()
    {
        Proxy = null,
        AutomaticDecompression = DecompressionMethods.GZip,
        SslProtocols =
            System.Security.Authentication.SslProtocols.Tls
            | System.Security.Authentication.SslProtocols.Tls12
            | System.Security.Authentication.SslProtocols.Tls13
    };
    protected static readonly HttpMessageHandler loggerHandler = new LoggingHandler(handler);

    HttpClient newhttpClient = new(handler: loggerHandler, disposeHandler: false)
    {
        BaseAddress = new Uri(Host),
        // 设置超时时间
        Timeout = new TimeSpan(TimeSpan.TicksPerMillisecond * TimeoutInMilliSeconds),
    };
}

标签:logBuilder,C#,AppendLine,request,responseMessage,使用,new,LoggingHandler,HttpClien
From: https://www.cnblogs.com/wolfife/p/17215771.html

相关文章

  • AcWing3305 -- 建图
    1.题目描述给定我们一些初始作物,和作物之间杂交的规则(作物\(a\)和作物\(b\)杂交产生种子\(c\),花费作物\(a\)和作物\(b\)成熟时间的最大值),让我们求,某个作物\(T......
  • Mockk详解
    简述mockk和mockito类似,都是在测试环境下制造testdouble的测试框架在kotlin环境下mockk比mockito更加优秀mockito在kotlin的缺陷mockito的when方法在kotl......
  • 2019 ICPC Asia-East Continent Final
    D考虑树形DP,记\(f[u],g[u]\)分别为最终回到u/停在子树中的最晚第一次到达u的时间。原本以为在枚举了最后一个的情况下,遍历子树的顺序是以f升序的,(因为只有最后一个不对后面......
  • C - Make Takahashi Happy
    题目大意:左上角走到右下角,经过的路径权值连起来不能有重复,把没有重复的路径的条数加起来输出。我自己写的时候也磕磕绊绊,主要是自己模拟一边,理明白了就好了#include<ios......
  • nacos报错 Caused by: com.alibaba.nacos.api.exception.NacosException: java.io.IOE
    麻麻劈,根据这个报错一顿ulimit -n 修改打开文件数,鸡儿报错一直在。 最终修改 vi/etc/sysctl.conf增加三项:fs.inotify.max_queued_events=32768fs.inotify.ma......
  • 使用vscode + vite + vue3+ vant 搭建vue3脚手架
    【术栈】开发工具:VSCode代码管理:Git前端框架:Vue3构建工具:Vite路由:vue-router4x状态管理:vuex4xAJAX:axiosUI库:vant数据模拟:mockjscss预处理:sass构建vue3项目1,安装 vite......
  • TCPIP网络编程 -- (四)基于 TCP 的服务端客户端(1)
    TCP/IP网络编程--(四)基于TCP的服务端/客户端(1)4.2实现基于CP的服务器端/客户端等待连接请求阶段#include<sys/socket.h>intlisten(intsock,intbacklog);......
  • TCPIP网络编程 -- (五)基于 TCP 的服务端客户端(2)
    TCP/IP网络编程--(五)基于TCP的服务端/客户端(2)5.1回声服务器的完美实现由于上一章末尾提到的问题write(sock,message,strlen(message));str_len=read(sock,mess......
  • Swift 中 extension 的使用
    在Swift中,extension是一种非常有用的语言特性,它可以为一个已有的类型(包括类、结构体和枚举)添加新的属性、方法、下标和协议等功能,而无需修改原始类型的定义。使用exten......
  • ShowDoc在线API文档
    官方文档: https://www.showdoc.com.cn/helpdocker部署说明:#原版官方镜像安装命令(中国大陆用户不建议直接使用原版镜像,可以用后面的加速镜像)dockerpullstar7th......