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.

Проводя пару часов, исследуя это в Google, я придумал нелегкий ответ на вопрос о том, что должно быть относительно прямой проблемой.

Есть ли у кого-нибудь указатели?

Ответ 1

Хорошо, с помощью коллеги и некоторых экспериментов я обнаружил, что это можно сделать с помощью некоторых защищенных свойств и методов, доступных через отражение:

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

Это работает для меня, по крайней мере.

Ответ 2

Вы можете добавить в заголовок таким образом. Это способ добавления учетных данных в запрос до того, как он войдет в последовательность аутентификации.

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