Я работаю над проектом ASP.NET Web Api и заставил его принимать информацию о версии в URL-адресе.
Например:
- API/v1/МойКонтроллер
- API/v2/МойКонтроллер
Теперь я хотел бы получить версию запроса v1, v2 внутри пользовательского LayoutRenderer для Nlog
. Обычно я бы сделал это, как в приведенном ниже примере.
[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
Я полагаю, это потому, что я использую асинхронные оболочки. для NLog
и некоторые вызовы перед регистратором также Async
.
Пример логгера, вызываемого Async внутри Ninject.Extensions.WebApi.UsageLogger. На данный момент у 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, но мне бы очень хотелось более универсальное решение, в котором я всегда могу полагаться на информацию о версии в своем журнале.
Изменить: обновлен вопрос, чтобы он стал более конкретным и содержал больше деталей.