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

时间:2015-03-02 22:06:16

标签: c# asp.net-mvc-5 owin owin-middleware

根据question的原因,为什么来自Asp.Net Identity的ApplicationDbContext被创建并按照请求处理两次,我做了一些研究,为什么会发生这种情况。我发现ApplicationDbContextHttpRequest实际创建一次,但在使用Owin管道时,将在HttpRequest结束后第二次创建Owin中间件。

因此,ApplicationDbContext确实是第二次创建,当用户点击一个链接时,会产生每WebRequest创建两次对象的印象。

经过大量研究后,我决定在不使用任何身份验证的情况下启动一个简单的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));
            });
        }
    }
}

然后将其添加到Index的{​​{1}} ActionMethod中,以检查创建的对象是否仍然存在。

HomeController

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

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 之后,中间件是否已创建并再次输入?任何人有任何想法或解释?

重现的步骤:

  1. 在VS 2013中启动新的MVC 5项目,无需身份验证
  2. 使用包管理器中的end of 'normal' request从NuGet添加Owin
  3. 向项目添加启动类,如上所示
  4. 将代码添加到Install-Package Microsoft.Owin.Host.SystemWeb
  5. Index ActionMethod
  6. 在调试模式下按F5
  7. 点击' Home'开始页面上的链接
  8. 观察输出中的输出(或立即视VS设置而定)窗口

1 个答案:

答案 0 :(得分:5)

这里最有可能发生的事情是实际上有两个单独的请求正在发生。第一个是您的主页/索引视图,第二个可能是浏览器发出favicon.ico之类的请求。 (浏览器倾向于自动执行此操作。)

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

相关问题