我正在开发一个 ASP.NET Web Api 项目,并使其接受 url 中的版本信息。
例如:
- api/v1/MyController
- api/v2/MyController
现在我想在自定义 LayoutRenderer 中获取请求版本v1、v2Nlog
。通常我会像下面的例子那样做。
[LayoutRenderer("Version")]
public class VersionLayoutRenderer : LayoutRenderer
{
protected override void Append(System.Text.StringBuilder builder, NLog.LogEventInfo logEvent)
{
var version = HttpContext.Current.Request.RequestContext.RouteData.Values["Version"];
builder.Append(version);
}
}
问题: HttpContext.Current
是NULL
我相信这是因为我使用Async 包装器,NLog
并且 Logger 之前的一些调用也是Async
.
在 Ninject.Extensions.WebApi.UsageLogger 中调用 Async 的记录器示例。此时,HttpRequestMessage
我们需要获取版本的所有信息。
/// <summary>
/// Initializes a new instance of the <see cref="UsageHandler" /> class.
/// </summary>
public UsageHandler()
{
var kernel = new StandardKernel();
var logfactory = kernel.Get<ILoggerFactory>();
this.Log = logfactory.GetCurrentClassLogger();
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var startTime = DateTime.Now;
// Log request
await request.Content.ReadAsStringAsync().ContinueWith(c =>
{
this.Log.Info("{0}: {1} called from {2}", request.Method, HttpUtility.UrlDecode(request.RequestUri.AbsoluteUri), ((HttpContextBase)request.Properties["MS_HttpContext"]).Request.UserHostAddress);
this.Log.Info("Content-Type: {0}, Content-Length: {1}", request.Content.Headers.ContentType != null ? request.Content.Headers.ContentType.MediaType : string.Empty, request.Content.Headers.ContentLength);
this.Log.Info("Accept-Encoding: {0}, Accept-Charset: {1}, Accept-Language: {2}", request.Headers.AcceptEncoding, request.Headers.AcceptCharset, request.Headers.AcceptLanguage);
if (!string.IsNullOrEmpty(c.Result))
{
if (this.MaxContentLength > 0 && c.Result.Length > this.MaxContentLength)
{
this.Log.Info("Data: {0}", HttpUtility.UrlDecode(c.Result).Substring(0, this.MaxContentLength - 1));
}
else
{
this.Log.Info("Data: {0}", HttpUtility.UrlDecode(c.Result));
}
}
});
var response = await base.SendAsync(request, cancellationToken);
// Log the error if it returned an error
if (!response.IsSuccessStatusCode)
{
this.Log.Error(response.Content.ReadAsStringAsync().Result);
}
// Log performance
this.Log.Info("Request processing time: " + DateTime.Now.Subtract(startTime).TotalSeconds + "s");
return response;
}
问题以通用VersionLayoutRenderer
方式制作作品
的最佳方式是什么?我可以添加一个 MessageHandler 并将 HttpRequest 绑定到某个异步范围吗?如果是这样,任何指导方针将不胜感激,因为我仍然习惯。 Ninject
目前我将版本信息直接添加到 UsageHandler 中的日志调用中,但我真的想要一个更通用的解决方案,我总是可以依赖日志中的版本信息。
编辑:将问题更新为更具体并包含更多详细信息。