为什么在HttpRequest结束后第二次创建了owin中间件

根据为什么来自Asp.Net Identity的ApplicationDbContext被创建并按照请求处理两次的问题后,我做了一些研究,为什么会发生这种情况。 我发现每个HttpRequest创建一次ApplicationDbContext但是当使用Owin管道时,将在HttpRequest结束后第二次创建Owin Middleware。

因此,当用户单击一个链接时,确实会第二次创建ApplicationDbContext从而给出每个WebRequest创建对象两次的印象。

经过大量的研究,我决定在不使用任何身份validation的情况下启动一个简单的MVC 5项目。 从NuGet添加Owin中间件后,我创建了以下Owin Middleware组件。 这基本上检查HttpContext字典中是否存在一些假对象,如果不存在则创建一个伪对象。 输出将写入调试窗口以使事情变得简单。

 [assembly: OwinStartupAttribute(typeof(MvcPlain.Startup))] namespace MvcPlain { public class Startup { public static int Counter; public static string FakeKeyName; public void Configuration(IAppBuilder app) { app.Use(async (context, next) => { Debug.WriteLine("Owin middleware entered => begin request"); FakeKeyName = "owinKey" + Counter.ToString(); var fakeKeyPresent = HttpContext.Current.Items.Contains(FakeKeyName); Debug.WriteLine(string.Format("{0} key present in HttpContext?: {1}", FakeKeyName, fakeKeyPresent)); if (!HttpContext.Current.Items.Contains(FakeKeyName)) { Counter += 1; HttpContext.Current.Items.Add(FakeKeyName, "someValue"); } await next.Invoke(); Debug.WriteLine("Owin middleware exited => end request"); var keyStillPresent = HttpContext.Current.Items.Contains(FakeKeyName); Debug.WriteLine(string.Format("{0} still present in HttpContext?: {1}", FakeKeyName, keyStillPresent)); }); } } } 

然后将其添加到HomeControllerIndex ActionMethod以检查创建的对象是否仍然存在。

 public ActionResult Index() { Debug.WriteLine("Index actionmethod called"); var fakeKeyPresent = HttpContext.Items.Contains(Startup.FakeKeyName); Debug.WriteLine(string.Format("{0} key present in HttpContext?: {1}", Startup.FakeKeyName, fakeKeyPresent)); return View(); } 

运行时,输出窗口显示以下输出(为清晰起见添加了注释):

 --- home link clicked --- Owin middleware entered => begin request owinKey2 key present in HttpContext?: False Index actionmethod called owinKey2 key present in HttpContext?: True Owin middleware exited => end request owinKey2 key still present in HttpContext?: True --- end of 'normal' request --- Owin middleware entered => begin request owinKey3 key present in HttpContext?: False Owin middleware exited => end request owinKey3 key still present in HttpContext?: True 

那么,为什么在end of 'normal' request的评论end of 'normal' request ,中间件是否已创建并再次输入? 任何人有任何想法或解释?

重现步骤:

  1. 无需身份validation即可在VS 2013中启动新的MVC 5项目
  2. 使用包管理器中的Install-Package Microsoft.Owin.Host.SystemWeb从NuGet添加Owin
  3. 如上所示,向项目添加启动类
  4. 将代码添加到HomeControllerIndex ActionMethod
  5. 在调试模式下按F5
  6. 单击起始页面上的“主页”链接
  7. 观察输出中的输出(或立即取决于您的VS设置)窗口

这里最有可能发生的是实际上发生了两个不同的请求。 第一个是您的Home / Index视图,第二个可能是浏览器请求favicon.ico东西。 (浏览器倾向于自动执行此操作。)

在中间件的开头,插入一个调试助手,显示context.Request.Path的值,以查看每次请求的URL。