c# - script - iis add a new managed http handler
Publicar formularios en un 404+HttpHandler en IIS7: ¿por qué todos los datos de POST han desaparecido? (5)
Dado que IIS7 usa .net de arriba hacia abajo, no habría ninguna sobrecarga de rendimiento al usar un HttpModule. De hecho, hay varios HttpModules administrados que siempre se usan en cada solicitud. Cuando se activa el evento BeginRequest, es posible que el SessionStateModule no se haya agregado a la colección de Módulos, por lo que si intenta manejar la solicitud durante este evento, no estará disponible ninguna información del estado de la sesión. Establecer la propiedad HttpContext.Handler inicializará el estado de la sesión si el controlador solicitado lo necesita, por lo que puede simplemente configurar el controlador en su elegante página 404 que implementa IRequiresSessionState. El siguiente código debería ser el truco, aunque es posible que deba escribir una implementación diferente para el método IsMissing ():
using System.Web;
using System.Web.UI;
class Smart404Module : IHttpModule
{
public void Dispose() {}
public void Init(HttpApplication context)
{
context.BeginRequest += new System.EventHandler(DoMapping);
}
void DoMapping(object sender, System.EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
if (IsMissing(app.Context))
app.Context.Handler = PageParser.GetCompiledPageInstance(
"~/404.aspx", app.Request.MapPath("~/404.aspx"), app.Context);
}
bool IsMissing(HttpContext context)
{
string path = context.Request.MapPath(context.Request.Url.AbsolutePath);
if (System.IO.File.Exists(path) || (System.IO.Directory.Exists(path)
&& System.IO.File.Exists(System.IO.Path.Combine(path, "default.aspx"))))
return true;
return false;
}
}
Editar: agregué una implementación de IsMissing ()
Nota: En IIS7, el módulo de estado de la sesión no se ejecuta globalmente de manera predeterminada. Hay dos opciones: Habilite el módulo de estado de la sesión para todas las solicitudes (consulte mi comentario anterior sobre la ejecución de módulos administrados para todos los tipos de solicitudes) o puede usar el reflejo para acceder a los miembros internos dentro de System.Web.dll.
OK, esto puede sonar un poco confuso y complicado, así que tengan paciencia conmigo.
Hemos escrito un marco que nos permite definir URL amigables. Si navega a cualquier URL arbitraria, IIS intenta mostrar un error 404 (o, en algunos casos, 403; 14 o 405). Sin embargo, IIS está configurado para que todo lo dirigido a esos errores específicos se envíe a un archivo .aspx. Esto nos permite implementar un HttpHandler para manejar la solicitud y hacer cosas, lo que implica encontrar una plantilla asociada y luego ejecutar lo que esté asociado con ella.
Ahora, todo esto funciona en IIS 5 y 6 y, hasta cierto punto, en IIS7, pero por una sola vez, lo que sucede cuando publica un formulario.
Cuando publica un formulario en una URL inexistente, IIS dice "ah, pero esa url no existe" y arroja un error 405 "método no permitido". Dado que le estamos diciendo a IIS que redirija esos errores a nuestra página .aspx y, por lo tanto, lo gestione con nuestro HttpHandler, normalmente esto no es un problema. Pero a partir de IIS7, toda la información de POST ha desaparecido después de ser redireccionada al 405. Por lo tanto, ya no puedes hacer las cosas más triviales que involucran formularios.
Para resolver esto, hemos intentado utilizar un HttpModule, que conserva los datos POST pero parece no tener una sesión inicializada en el momento adecuado (cuando es necesario). También intentamos usar un HttpModule para todas las solicitudes, no solo las solicitudes faltantes que llegan a 404/403; 14/405, pero eso significa que cosas como imágenes, css, js, etc. están siendo manejadas por el código .NET, que es terriblemente ineficiente.
Lo que me lleva a la verdadera pregunta: ¿alguien se ha encontrado alguna vez con esto, y alguien tiene algún consejo o sabe qué hacer para que las cosas funcionen nuevamente? Hasta ahora, alguien sugirió usar el propio módulo de reescritura de URL de Microsoft. ¿Ayudaría esto a resolver nuestro problema?
Gracias.
Sí, definitivamente recomendaría la reescritura de URL (usando IIS7 de Microsoft, una o una de las muchas alternativas). Esto está específicamente diseñado para proporcionar URL amigables, mientras que los documentos de error son un respaldo de último momento para las fallas, lo que tiende a afectar a los datos entrantes por lo que puede no ser lo que esperabas.
Solo una suposición: el controlador especificado en% windir% / system32 / inetsrv / config / applicationhost.config de IIS7 que está manejando su solicitud no permite que el verbo POST llegue a pasar, y está evaluando esa regla antes de determinar si la URL no existe
Microsoft lanzó una revisión para esto:
El problema en IIS 7 de variables posteriores que no se pasan a manejadores de errores personalizados se soluciona en el Service Pack 2 para Vista. No lo he probado en Windows Server, pero estoy seguro de que también se solucionará allí.