记录 WebClient 的请求、响应和异常

Posted

技术标签:

【中文标题】记录 WebClient 的请求、响应和异常【英文标题】:Logging requests, responses and exceptions of WebClient 【发布时间】:2015-05-21 11:46:53 【问题描述】:

我想记录(保存到数据库或文件等)所有请求和响应,但 WebClient 除外。 我使用派生类: public class GzipWebClient : WebClient ...

我应该在哪里捕获带有数据的上传请求、下载响应和异常?还是应该重写一些方法?

我可以使用“protected override WebRequest GetWebRequest(Uri address)”来捕获数据吗?

一些使用:

    private T GetDeserializedResponse<T>(string url)
    
        using (var wc = new GzipWebClient())
        
            wc.Encoding = Encoding.UTF8;
            string fullUrl = BaseUrl + url;
            string response = wc.DownloadString(fullUrl);

            try
            
                return JsonConvert.DeserializeObject<T>(response);
            
            catch
            
                _logger.Error(response);
                throw;
            
        
    

        string url = shop.Warehouse != null ?
            string.Format("/api/v1/cabinet/0/shop_create.json", MasterApiKey) :
            string.Format("/api/v1/0/shop_create.json", MasterApiKey);

        string name = shop.Name;
        string namePostfix = DateTime.Now.ToString("yyMMddhhmmss");
        if ((name + namePostfix).Length > 64)
            name = name.Substring(0, 64 - namePostfix.Length);

        string data = shop.Warehouse != null ?
            string.Format("name=0&warehouse=1&address=2", name + namePostfix, shop.Warehouse.Id, shop.Address) :
            string.Format("name=0&address=1", name + namePostfix, shop.Address);

        using (var wc = new GzipWebClient())
        
            wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
            wc.Encoding = Encoding.UTF8;

            string fullUrl = BaseUrl + url;

            string response = wc.UploadString(fullUrl, data);

            var shopData = JsonConvert.DeserializeObject<DDeliveryCreateShopResponse>(response);

            if (!shopData.Success)
            
                throw new DeliveryCreateStoreException(shop.Name);
            

            if (string.IsNullOrEmpty(shopData.IdKeyPair.Key))
            
                throw new DeliveryCreateStoreException(shop.Name);
            

            shop.Id = shopData.IdKeyPair.Id;
            shop.Key = shopData.IdKeyPair.Key;
            return shop;
        

【问题讨论】:

请放一些代码,调用,除了方法之外的其他东西; GzipWebClient 做什么?我们可以查看您如何/何时加载网页吗? 【参考方案1】:

对于调用网络服务,如果你使用.Net 4.5,使用HttpClient会更容易。

你可以像这样创建LoggingHandler

public class LoggingHandler : DelegatingHandler

    public LoggingHandler()
        : this(new HttpClientHandler())
     

    public LoggingHandler(HttpMessageHandler innerHandler)
        : base(innerHandler)
     

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    
        var activityId = Guid.NewGuid();
        using (new Tracer("Service Call", activityId))
        
            var entry = new LogEntry  Severity = TraceEventType.Verbose, Title = "Request" ;
            if (Logger.ShouldLog(entry))
            
                entry.Message = request.ToString();
                if (request.Content != null)
                
                    entry.Message += Environment.NewLine;
                    entry.Message += await request.Content
                        .ReadAsStringAsync()
                        .ConfigureAwait(false);
                
                Logger.Write(entry);
            

            var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

            entry = new LogEntry  Severity = TraceEventType.Verbose, Title = "Response" ;
            if (Logger.ShouldLog(entry))
            
                entry.Message = response.ToString();
                if (response.Content != null)
                    entry.Message += await response.Content
                        .ReadAsStringAsync()
                        .ConfigureAwait(false);

                Logger.Write(entry);
            

            return response;
        
    

然后创建HttpClient:

//hook all http request and response
var hc = new HttpClient(new LoggingHandler());

HttpClient 类的文档: https://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.118%29.aspx

比较HttpClientWebClient Need help deciding between HttpClient and WebClient

【讨论】:

【参考方案2】:

你必须在你的应用程序的最低点记录异常,如果你有它,在你的 DAL 中,以便处理你的数据库的异常。

【讨论】:

不,在我的情况下,我必须记录(或在分析日志后执行其他操作)逻辑中适用于指定外部服务的任何响应(200、404、500 等)。

以上是关于记录 WebClient 的请求、响应和异常的主要内容,如果未能解决你的问题,请参考以下文章

WebClient 请求期间发生异常。在 Windows 手机中

如何记录 spring-webflux WebClient 请求 + 响应详细信息(正文、标头、elasped_time)?

Webflux WebClient中如何自定义异常?

如何使用 WebClient 反应式 Web 客户端发送带有 zip 正文的 POST 请求

使用带有阻塞/同步请求的 Spring WebClient 使用 try/catch 捕获异常

使用 spring webclient 对 http 请求进行可读的调试日志记录