2

询问了为什么ApplicationDbContext每次请求都会创建和处理两次来自 Asp.Net 的身份之后,我做了一些研究,为什么会发生这种情况。我发现实际上ApplicationDbContext每次创建一次,HttpRequest但是在使用 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));
            });
        }
    }
}

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

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,中间件又被创建并输入了呢?任何人有任何想法或解释?

重现步骤:

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

1 回答 1

5

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

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

于 2015-03-02T22:30:24.260 回答