我尝试在一个嵌套的 HttpModule
中使用 EndRequest
事件处理程序修改标头,但在 MVC 5.2.2 和 .NET 4.6.2 上出现了一些奇怪的行为。如果我不在顶层的 HttpModule
中修改 EndRequest
,那么即使我知道已经在嵌套的 HttpModule
上调用了 Init
,它的事件处理程序似乎也永远不会触发。
我的问题是,为什么我的代码会阻止 "TestNested" 标头出现在响应标头中,除非我包含已注释掉的添加无操作的 EndRequest
事件处理程序的代码?
动态注册我的顶层 HttpModule
[assembly: PreApplicationStartMethod(typeof(PreApplicationStartClass), "Start")]
namespace MyNamespace
{
public class PreApplicationStartClass
{
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(TopHttpModule));
}
}
}
从一个顶级模块调用Init
,以便初始化所有其他HttpModules
namespace MyNamespace
{
public class TopHttpModule: IHttpModule
{
private readonly Lazy<IEnumerable<IHttpModule>> _modules =
new Lazy<IEnumerable<IHttpModule>>(RetrieveModules);
private static IEnumerable<IHttpModule> RetrieveModules()
{
return DependencyResolver.Current.GetServices<IHttpModule>();
}
public void Init(HttpApplication context)
{
var modules = _modules.Value;
foreach (var module in modules
.Where(module => module.GetType() != typeof(TopHttpModule)))
{
module.Init(context);
}
context.BeginRequest += (sender, e) =>
{
var app = sender as HttpApplication;
if (app != null)
{
//This shows that NestedHttpModule was found
app.Context.Response.Headers.Add(
"TestModules",
string.Join(",", modules.Select(_ => _.GetType().ToString())));
}
};
//Add this and the NestedHttpModule EndRequest handler works
//context.EndRequest += (sender, e) =>
//{
// //Do Nothing
//};
}
public void Dispose()
{
var modules = _modules.Value;
foreach (var disposable in modules
.Where(disposable => disposable.GetType() != typeof(TopHttpModule)))
{
disposable.Dispose();
}
}
}
}
在 EndRequest
事件处理程序中修改一些头信息
namespace MyNamespace
{
public class NestedHttpModule: IHttpModule
{
public void Init(HttpApplication context)
{
//This gets called whether or not the TopHttpModule modifies context.EndRequest
MvcHandler.DisableMvcResponseHeader = true;
context.EndRequest += Application_EndRequest;
}
public void Application_EndRequest(object sender, EventArgs e)
{
var app = sender as HttpApplication;
if (app != null && app.Context != null)
{
//This doesn't appear to be called unless TopHttpModule modifies context.EndRequest
app.Context.Response.Headers.Add("TestNested", "Found");
}
}
public void Dispose()
{
//Do Nothing
}
}
}
Context.ApplicationInstance.CompleteRequest()
。几年前我遇到了这样一种情况,应用程序接收请求后会做其他事情,并在不让请求完成的情况下进行重定向。我相信这就是我用来处理这个问题的方法。 - Bardicer