在询问了为什么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));
});
}
}
}
然后将此添加到 的Index
ActionMethodHomeController
以检查创建的对象是否仍然存在。
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
,中间件又被创建并输入了呢?任何人有任何想法或解释?
重现步骤:
- 在 VS 2013 中启动一个新的 MVC 5 项目,无需身份验证
Install-Package Microsoft.Owin.Host.SystemWeb
在包管理器中使用 NuGet 添加 Owin- 如上图在项目中添加启动类
- 将代码添加到
Index
ActionMethod 的HomeController
- 在调试模式下按 F5
- 单击开始页面上的“主页”链接
- 在输出(或立即取决于您的 VS 设置)窗口中观看输出