在question之后根据为什么每个请求都会创建和处理来自 Asp.Net Identity 的 ApplicationDbContext
两次,我做了一些研究为什么会发生这种情况。我发现 ApplicationDbContext
实际上每个 HttpRequest
创建一次,但是当使用 Owin 管道时,Owin 中间件将在 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));
});
}
}
}
然后将其添加到 HomeController
的 Index
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
之后,又创建并输入中间件呢?有人有任何想法或解释吗?
重现步骤:
- 在 VS 2013 中启动一个新的 MVC 5 项目,无需身份验证
- 使用包管理器中的
Install-Package Microsoft.Owin.Host.SystemWeb
从 NuGet 添加 Owin - 将启动类添加到项目中,如上所示
- 将代码添加到
HomeController
的Index
ActionMethod - 在 Debug模式下按 F5
- 点击起始页上的“主页”链接
- 在输出(或立即取决于您的 VS 设置)窗口中观察输出
最佳答案
这里最有可能发生的情况是,实际上发生了两个单独的请求。第一个是您的主页/索引 View ,第二个可能是浏览器发出对 favicon.ico
之类的请求。 (浏览器往往会自动执行此操作。)
在中间件的开头插入一个调试帮助程序,该帮助程序会显示 context.Request.Path
的值,以查看每次请求的 URL。
关于c# - 为什么HttpRequest结束后会第二次创建owin中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28820346/