我想在整个处理请求中维护一个ID(Guid.NewGuid()
就足够了),以便稍后我可以检查给定ID的日志。我还在响应头(和消息)中将ID返回给调用者,以防出现错误,他们有一个引用。
首先,我在应用程序的Global.asax Application_BeginRequest()
方法中执行了此操作,我将ID放在HttpContext.Current.Items
集合中。
protected void Application_BeginRequest(object sender, EventArgs e)
{
var context = HttpContext.Current;
if (context != null)
{
var reqguid = Guid.NewGuid().ToString("D");
context.Items.Add("sessionid", reqguid);
}
}
这在以前的应用程序中运行良好,但我对在“现代”Web API应用程序中使用HttpContext
感到有些不确定。
然后我转向动作过滤器,因为显然这是Web API的蜜蜂膝盖
public class ManageRequestHeadersFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
actionContext.Request.Properties.Add("sessionid", Guid.NewGuid().ToString("D"));
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var sessionId = actionExecutedContext.Request.Properties["sessionid"].ToString();
if (sessionId != null)
{
actionExecutedContext.Response.Headers.Add("App-Session-Id", sessionId);
}
}
}
...
config.Filters.Add(new ManageRequestHeadersFilter());
这也正常,直到我想到Request
构造函数中的ApiController
对象设置一个帮助属性到ID。由于控制器构造函数在过滤器之前运行,因此Request
对象为空。同样,我可能会使用HttpContext.Current
方式,但这会超过过滤器的目的。
我还想过使用依赖注入(已经使用Autofac)将ID注入到构造函数中,这也是有效的,但是现在我会做一些倒退的事情,这让我感到很奇怪。< / p>
我的感觉是,将ID作为控制器构造函数参数传递最终将成为赢家,因为在单元测试时,我不应该依赖任何HTTP。
这已经是最好的做法吗?