2010-11-03 13 views
10

Esto parece una operación simple.HttpModule para agregar encabezados para solicitar

Tenemos una necesidad en nuestro entorno de desarrollo (que se ejecuta en XP/IIS 5) para agregar algunos encabezados en cada HttpRequest que llegan a nuestra aplicación. (Esto es para simular un entorno de producción que no tenemos disponible en dev). A primera vista, esto parecía una sencilla HttpModule, a lo largo de las líneas de:

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

    public void Dispose(){} 
} 

Pero en tratar de hacer eso, encuentro de sólo lectura que la colección encabezados de la solicitud es, y el método Add falla con una excepción OperationNotSupported.

Pasando un par de horas investigando esto en Google, no he encontrado una respuesta fácil a lo que debería ser un problema relativamente sencillo.

¿Alguien tiene punteros?

+0

Existe la posibilidad de modificar el flujo de respuesta. ¿Tiene algo específico que pueda manejar y reemplazar? – brumScouse

+0

No quiero modificar la respuesta. Necesito modificar la solicitud y enviarla al resto de la cadena, finalizando en mi aplicación MVC. Cuando llegue a mi aplicación, mi aplicación debe poder ver los encabezados que estoy tratando de insertar en este módulo. –

Respuesta

15

Está bien, con la ayuda de un compañero de trabajo y un poco de experimentación, he encontrado que esto se puede hacer con la ayuda de algunas propiedades y métodos protegidos accede a través de la reflexión:

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

Esto funciona para mí, al menos.

+0

¡Tenemos un ganador! –

+0

Esto está tan mal. Lo usé para agregar parámetros a la solicitud (también son de solo lectura). Sin embargo, no es necesario convertir el valor de ArrayList en ese caso, solo una cadena. +1 – iandisme

+0

¡Impresionante! Lo usé para crear un método de extensión para cuando necesitaba agregar un encabezado a HttpRequest para mis pruebas. https://gist.github.com/mrstebo/81288a96f55c0b74f6c5b37ee17533a6 – mrstebo

0

Puede agregar al encabezado de esta manera. Esta es una forma de agregar información de credenciales a la solicitud antes de que ingrese la secuencia de autenticación.

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

No estoy seguro, y, dado que es un año y medio después, todavía no tengo un entorno de prueba para probarlo, pero creo que lo harás. encuentre que Headers.Add fallará con excepción de OperationNotSupported como lo hizo en mi ejemplo original. Puedo estar equivocado ... –

+0

Probé este método y obtuve la misma excepción de OperationNotSupported La solución de Dave Hanna me funcionó – Franklin

Cuestiones relacionadas