【问题标题】:HttpModule to add headers to requestHttpModule 为请求添加标头
【发布时间】:2011-05-04 17:15:09
【问题描述】:

这似乎是一个简单的操作。

我们需要在我们的开发环境中(在 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(){}
}

但是在尝试这样做时,我发现 Request 的 Headers 集合是只读的,并且 Add 方法失​​败并出现 OperationNotSupported 异常。

我花了几个小时在 Google 上研究这个问题,但对于应该是一个相对简单的问题,我没有找到简单的答案。

有人指点一下吗?

【问题讨论】:

  • 可以修改响应流。你有什么具体的东西可以处理和替换吗?
  • 我不想修改响应。我需要修改请求,并将其发送到链的其余部分,最终以我的 MVC 应用程序结束。当它到达我的应用程序时,我的应用程序必须能够看到我尝试在此模块中插入的标题。

标签: c# iis http-headers httprequest


【解决方案1】:

您可以通过这种方式添加到 Header。这是一种在请求进入身份验证序列之前向请求添加凭据信息的方法。

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

【讨论】:

  • 我也不确定,而且因为已经过了一年半了,所以我还没有测试环境可以尝试,但是相信你会发现Headers.Add会失败并出现 OperationNotSupported 异常,就像我在原始示例中所做的那样。我可能错了……
  • 我尝试了这种方法并且确实得到了相同的 OperationNotSupported 异常 Dave Hanna 的解决方案对我有用
【解决方案2】:

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

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

这至少对我有用。

【讨论】:

  • 我们赢了! ?
  • 这是大错特错。我用它为请求添加参数(它们也是只读的)。不过,在这种情况下,无需将其设为 ArrayList 的值 - 只是一个字符串。 +1
  • 太棒了!当我需要为我的测试向 HttpRequest 添加标头时,我使用它来创建扩展方法。 gist.github.com/mrstebo/81288a96f55c0b74f6c5b37ee17533a6
猜你喜欢
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 2021-07-03
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 2012-12-01
相关资源
最近更新 更多