2010-11-03 102 views
10

这似乎是一个简单的操作。HttpModule向请求添加标头

我们有必要在我们的开发环境(在XP/IIS 5上运行)以一些头添加到每个HttpRequest的到达我们的应用程序。 (这是为了模拟我们在dev中没有的生产环境)。乍一看,这似乎是一个简单的HttpModule,沿着线:

public class Dev_Sim: IHttpModule 
{ 
    public void Init(HttpApplication app) 
    { 
     app.BeginRequest += delegate { app.Context.Request.Headers.Add("UserName", "XYZZY"); }; 
    } 

    public void Dispose(){} 
} 

但在试图做到这一点,我发现请求的头集合是只读的,而Add方法失败一个OperationNotSupported异常。

花费一两个小时在谷歌研究这个,我来了,没有简单的答案,什么应该是一个比较直接的问题。

有没有人有任何指针?

+0

有能力修改响应流。你有什么具体的东西可以得到处理和替换? – brumScouse 2010-11-03 20:10:31

+0

我不想修改回应。我需要修改请求,并将其发送到链的其余部分,最终以我的MVC应用程序结束。当它到达我的应用程序时,我的应用程序必须能够看到我试图在此模块中插入的标题。 – 2010-11-03 21:32:38

回答

15

好,有同事和一些实验的帮助下,我发现,这可能与部分受保护的属性和方法通过反射访问的帮助来完成:

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); 

这对我的作品,至少。

+0

我们有一个赢家! – 2016-01-06 03:00:39

+0

这是错的。我用它来为请求添加参数(它们也是只读的)。在这种情况下,不需要将它作为ArrayList的值 - 只是一个字符串。 +1 – iandisme 2016-10-27 14:35:39

+0

太棒了!我用这个来创建一个扩展方法,当我需要为我的测试添加一个头部到一个HttpRequest。 https://gist.github.com/mrstebo/81288a96f55c0b74f6c5b37ee17533a6 – mrstebo 2017-04-12 10:56:18

0

您可以添加到页眉这种方式。这是在输入认证序列之前向请求添加凭证信息的一种方式。

string cred = "UN:PW"; 
System.Web.HttpContext.Current.Request.Headers.Add("Authorization", "Basic " +Convert.ToBase64String(Encoding.ASCII.GetBytes(cred))); 
+2

我不确定,而且,由于这是一年半之后,我还没有一个测试环境来尝试它,但我相信你会发现Headers.Add和OperationNotSupported异常都会失败,就像它在我的原始示例中那样。我可能是错的... – 2012-02-22 16:13:28

+0

我试过这种方法,并得到了相同的OperationNotSupported异常戴夫汉娜的解决方案为我工作 – Franklin 2016-05-23 15:48:38