记录 WebClient 的请求、响应和异常
Logging requests, responses and exceptions of WebClient
我想记录(保存到数据库或文件等)除 WebClient 之外的所有请求和响应。
我使用派生 class: 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;
}
你必须在你的应用程序的最低点记录异常,如果你有 DAL,以便处理你的数据库的异常。
对于调用网络服务,如果您使用.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
class 的文档:
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.118%29.aspx
比较 HttpClient
和 WebClient
我想记录(保存到数据库或文件等)除 WebClient 之外的所有请求和响应。 我使用派生 class: 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;
}
你必须在你的应用程序的最低点记录异常,如果你有 DAL,以便处理你的数据库的异常。
对于调用网络服务,如果您使用.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
class 的文档:
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.118%29.aspx
比较 HttpClient
和 WebClient