问题描述
这似乎是一个简单的操作.
This seems like a simple operation.
我们需要在我们的开发环境(在 XP/IIS 5 上运行)向到达我们应用程序的每个 HttpRequest 添加一些标头.(这是为了模拟我们在 dev 中没有的生产环境).乍一看,这似乎是一个简单的 HttpModule,大致如下:
We have a need in our development environment (running on XP/IIS 5) to add some headers into each HttpRequest arriving at our application. (This is to simulate a production environment that we don't have available in dev). At first blush, this seemed like a simple HttpModule, along the lines of:
public class Dev_Sim: IHttpModule
{
public void Init(HttpApplication app)
{
app.BeginRequest += delegate { app.Context.Request.Headers.Add("UserName", "XYZZY"); };
}
public void Dispose(){}
}
但是在尝试这样做时,我发现请求的 Headers 集合是只读的,并且 Add 方法失败并出现 OperationNotSupported 异常.
But on trying to do that, I find that the Headers collection of the Request is read-only, and the Add method fails with an OperationNotSupported exception.
花了几个小时在 Google 上研究这个问题,我想出了一个相对简单的问题的简单答案.
Spending a couple hours researching this on Google, I've come up with no easy answer to what should be a relatively straight-forward problem.
有大佬指点一下吗?
推荐答案
好的,在同事的帮助下和一些实验,我发现这可以通过反射访问的一些受保护的属性和方法的帮助来完成:
Okay, with the assistance of a co-worker and some experimentation, I found that this can be done with the assistance of some protected properties and methods accessed through reflection:
var headers = app.Context.Request.Headers;
Type hdr = headers.GetType();
PropertyInfo ro = hdr.GetProperty("IsReadOnly",
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.FlattenHierarchy);
// Remove the ReadOnly property
ro.SetValue(headers, false, null);
// Invoke the protected InvalidateCachedArrays method
hdr.InvokeMember("InvalidateCachedArrays",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null, headers, null);
// Now invoke the protected "BaseAdd" method of the base class to add the
// headers you need. The header content needs to be an ArrayList or the
// the web application will choke on it.
hdr.InvokeMember("BaseAdd",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null, headers,
new object[] { "CustomHeaderKey", new ArrayList {"CustomHeaderContent"}} );
// repeat BaseAdd invocation for any other headers to be added
// Then set the collection back to ReadOnly
ro.SetValue(headers, true, null);
这至少对我有用.
这篇关于HttpModule 添加请求头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!