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

Ric*_*Net 2 c# owin asp.net-mvc-5 owin-middleware

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

因此,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));
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将其添加到IndexActionMethod中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();
}
Run Code Online (Sandbox Code Playgroud)

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

--- 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
Run Code Online (Sandbox Code Playgroud)

那么为什么在评论之后end of 'normal' request,中间件又被创建并进入?任何人有任何想法或解释?

重现步骤:

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

Ada*_*ras 5

这里最有可能发生的是实际上发生了两个不同的请求.第一个是你的家庭/索引视图,第二个可能是浏览器发出类似的请求favicon.ico.(浏览器倾向于自动执行此操作.)

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