【发布时间】:2012-10-18 21:03:20
【问题描述】:
我正在开发一个 ASP.NET Web Api 项目,并使其接受 url 中的版本信息。
例如:
- api/v1/MyController
- api/v2/MyController
现在我想在 Nlog 的自定义 LayoutRenderer 中获取请求版本 v1、v2。通常我会像下面的例子那样做。
[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 wrappers 用于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 中的日志调用中,但我真的想要一个更通用的解决方案,我可以始终依赖日志中的版本信息。
编辑:将问题更新为更具体并包含更多详细信息。
【问题讨论】:
-
你能把代码贴在你使用异步的地方吗
-
乔纳森,请查看更新后的问题,我希望它包含您需要的所有信息,否则请询问。
标签: c# asp.net-mvc ninject asp.net-web-api httpcontext