example current c# asp.net iis-7

current - httpcontext c# example



¿Solución para HttpContext.HideRequestResponse siendo interno? Detectar si HttpContext.Request está realmente disponible? (5)

Creo que tengo la solución para ti. Mantengo una biblioteca de registro y tengo el mismo problema que usted. Si es una solicitud web, estoy capturando algunos datos del HttpContext. Pero dependiendo de cómo se use la biblioteca de registro, puede ocurrir este mismo escenario. Así que aquí está mi solución. La solución clave para mí fue comprobar si el controlador era nulo o no.

if (System.Web.Hosting.HostingEnvironment.IsHosted && System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Handler != null && System.Web.HttpContext.Current.Request != null) { //access the Request object here }

Dependiendo de lo que esté intentando lograr, puede obtener algunas de las propiedades y configuraciones de la aplicación web desde System.Web.Hosting.HostingEnvironment

Estamos migrando una aplicación para usar el modo integrado de IIS7. En el código de biblioteca que está diseñado para funcionar ya sea dentro del contexto de una solicitud HTTP o no, comúnmente tenemos un código como este:

if (HttpContext.Current != null && HttpContext.Current.Request != null) { // do something with HttpContext.Current.Request } else { // do equivalent thing without HttpContext.. }

Pero en el modo integrado de IIS7, la verificación de HttpContext.Current.Request lanza una excepción cada vez que se llama a este código desde Application_Start .

protected void Application_Start(object sender, EventArgs e) { SomeLibrary.DoSomethingWithHttpContextCurrentDetection(); }

Resultados en:

System.Web.HttpException: la solicitud no está disponible en este contexto

¿Cómo puedo detectar si la solicitud está realmente disponible sin incluir estas llamadas en un controlador de excepciones y tomar medidas en función de si se genera una excepción o no?

Mirando HttpContext en Reflector veo que tiene un campo internal bool HideRequestResponse pero es interno, así que solo puedo acceder a él con reflexión y eso es frágil. ¿Hay una manera más oficial / aprobada de determinar si está bien llamar a HttpContext.Request ?

Esta publicación del blog sobre el tema dice que no se debe usar HttpContext , pero ¿cómo, en el código genérico de la biblioteca, puede determinar si está bien usar HttpContext ?

http://mvolo.com/iis7-integrated-mode-request-is-not-available-in-this-context-exception-in-applicationstart/

Estoy usando la BeginRequest trabajo mencionada allí, que es usar Application_BeginRequest y un campo initialized para inicializar solo una vez como parte de BeginRequest , pero eso se debe hacer en cada aplicación de llamada, mientras que prefiero hacer que el código de la biblioteca sea más sólido y manejar esta situación sin importar desde donde se llame.


He añadido un comentario, pero se oculta automáticamente.

Creo que es más importante tener una idea de qué es lo que necesita de la solicitud.

Por ejemplo, el enlace que proporcionó que proporciona una solución alternativa está buscando Request.ApplicationPath .

Si eso es realmente lo que estás buscando (para, digamos, cargar el archivo web.config vs el archivo app.config), puedes hacer esto:

if (HttpRuntime.AppDomainAppId != null) return WebConfigurationManager.OpenWebConfiguration(HttpRuntime.AppDomainAppVirtualPath); else return ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

Si esto (o HttpRuntime.ApplicationPath ) no es lo que realmente está buscando, sería útil saber qué propiedades de la Request está buscando. Tal vez haya una manera mejor y más segura de llegar allí.


Me gustaría refactorizar su código a esto:

if (IsRequestAvailable()) { // do something with HttpContext.Current.Request... } else { // do equivalent thing without HttpContext... } public Boolean IsRequestAvailable() { if (HttpContext.Current == null) return false; try { if (HttpContext.Current.Request == null) return false; } catch (System.Web.HttpException ex) { #if DEBUG // Testing exception to a magic string not the best practice but // it works for this demo. if (ex.Message == "Request is not available in this context") return false; throw; #else return false; #endif } return true; }

Su pregunta solicitó no usar el manejo de excepciones (supongo que por razones de rendimiento) y mi respuesta sí. Sin embargo, cambiando su código de usar "If (HttpContext.Current! = Null && HttpContext.Current.Request! = Null)" a "If (IsRequestAvailable ())" solo tiene un lugar para cambiar el código cuando encuentra un contesta como no usar el manejo de excepciones.


Me temo que la respuesta es que no puede obtener lo que desea: Microsoft ve este caso como una "circunstancia excepcional", por lo que generará una excepción.

Puede utilizar la reflexión como describe en su respuesta, pero no desea hacerlo, por lo que está limitada por la API que Microsoft ha proporcionado, para bien o para mal.

Si decides usar la reflexión, lo importante es el método HttpApplication.InitInternal , que es el que establece el indicador HideRequestResponse.

Espero que ayude. Le sugiero que presente un informe con Microsoft Connect .


Ni siquiera debe usar la Solicitud (o Respuesta) en Application_Start ya que la aplicación podría iniciarse sin una solicitud. Por lo tanto, en el futuro, su aplicación ni siquiera se ejecutará cuando otras partes del marco dejen de proporcionar el objeto de solicitud.

Si solo quiere piratearlo temporalmente, puede usar Reflection (si tiene una confianza superior a la media) o capturar una excepción (aunque no quiera) y almacenar el resultado en una variable estática o posiblemente usar un HttpContext estático envoltura

También puedes usar HttpRuntime.UsingIntegratedPipeline .

Entonces, el mejor enfoque es eliminar la dependencia de sus clases en HttpContext cuando se están inicializando o no inicializarlas en appstart.

¿Cuál es su razonamiento para usar Request en la aplicación? Para las estadísticas? ¿O simplemente decirle al usuario que despertó la aplicación?

Editado con código para explicar mejor:

public static class ContextWrapper { public static HttpRequest Request { get { HttpContext context = HttpContext.Current; if (context == null) return null; if (HttpRuntime.UsingIntegratedPipeline) { try { return context.Request; } catch (HttpException e) { /* Consume or log e*/ return null; } // Do not use message comparison - .NET translates messages for multi-culture environments. } return context.Request; } } }

Y en código:

if (ContextWrapper.Request != null) //...

O una forma más rápida controlada por el usuario:

public static class ContextWrapper2 { public static bool IsIis7IntegratedAppStart { get; set; } public static HttpRequest Request { get { if (ContextWrapper2.IsIis7IntegratedAppStart) return null; HttpContext context = HttpContext.Current; if (context == null) return null; return context.Request; } } }

Y en el inicio de la aplicación:

protected void Application_Start(object sender, EventArgs e) { yourLibraryNamespace.ContextWrapper2.IsIis7IntegratedAppStart = true; //... yourLibraryNamespace.yourClass.Init(); //... yourLibraryNamespace.ContextWrapper2.IsIis7IntegratedAppStart = false; }

Podría observar este comportamiento en su documentación y todo debería estar bien. El contexto similar a AppStart debería ser el único lugar donde se obtiene dicha excepción.

También podría implementar IDisposable en un miembro y usarlo en appStart con la instrucción using para que no se olvide de establecer IsIis7IntegratedAppStart = false .