2010-12-21 16 views
63

Tengo un servicio web ASP.Net de archivo único (un archivo .ashx que contiene una implementación IHttpHandler) que necesita poder devolver errores como respuestas con 500 Internal Server Error códigos de estado. Esto es algo relativamente sencillo de hacer en PHP:¿Cómo enviar un código de estado 500 en ASP.Net y todavía escribir en la respuesta?

header("HTTP/1.1 500 Internal Server Error"); 
header("Content-Type: text/plain"); 
echo "Unable to connect to database on $dbHost"; 

El ASP.Net (C#) se deberá:

Context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; 
Context.Response.ContentType = "text/plain"; 
Context.Response.Write("Unable to connect to database on " + dbHost); 

Por supuesto, esto no funciona como se esperaba; en su lugar, IIS intercepta el código de estado 500, transfiere todo lo que he escrito al objeto Response y envía información de depuración o una página de error personalizada, según cómo esté configurada la aplicación.

Mi pregunta: ¿cómo puedo suprimir este comportamiento IIS y enviar información de error directamente desde mi implementación IHttpHandler?

Esta aplicación es un puerto de PHP; el lado del cliente ya está escrito, así que estoy esencialmente atascado con esta especificación. Enviar errores con un código de estado 200 lamentablemente no se ajusta al molde.

Idealmente, me necesidad de controlar el comportamiento mediante programación, ya que esto es parte de un SDK que queremos distribuir sin ninguna "editar este archivo" y "cambiar esta configuración de IIS" instrucciones complementarias.

Gracias!

Editar: Ordenado. fue el boleto. Guau.

+2

Si es posible me gustaría evitar dar información interna, como la ubicación de base de datos en un sitio de producción - los hackers les encanta recibir estas cosas, hace que sus ataques mucho más fácil. – devstuff

+1

Buen punto, pero este es un servicio web seguro, no un sitio web. La conexión a la base de datos ni siquiera se ha intentado sin una autenticación HTTP previamente exitosa :) –

Respuesta

101

+5

Compatible con IIS7 - http://msdn.microsoft.com/en-us/library/system.web.httpresponse.tryskipiiscustomerrors%28v=VS.90%29.aspx – AUSteve

+0

Son respuestas como esta las que me hacen darme cuenta de que peinar a través de la referencia de objeto de marco se está convirtiendo en un arte perdido. Si pudiera votar dos veces, lo haría. –

0

Es posible que desee establecer una página CustomErrors (configurable a través de web.config). Puede almacenar su contenido entre las solicitudes de la Sesión (o mediante un mecanismo alternativo) y luego tener asp.net configurado para mostrar la página de error personalizada que a su vez muestra su salida personalizada.

Sin embargo, una palabra de advertencia: si el 500 está siendo causado por un problema fundamental con la aplicación (es decir, StackOverflowException) e intenta mostrar una página que depende de asp.net (es decir, MyCustomErrors.aspx), puede terminar en un bucle.

Para obtener más información, consulte this page.

+0

Gracias Bobby. Estoy familiarizado con la directiva customErrors, pero lamentablemente se basa en la edición del archivo web.config, que nuestros usuarios pueden no ser capaces de hacer.Una posible solución es modificar el archivo web.config programáticamente, pero esto es obviamente menos que ideal. –

8

He utilizado lo siguiente en el pasado y he podido lanzar un error 503 con un mensaje personalizado utilizando el código que se muestra a continuación en el método Page_Load. Uso esta página detrás de un equilibrador de carga como la página de ping para que el equilibrador de carga sepa si un servidor está en servicio o no.

Espero que esto ayude.

 protected void Page_Load(object sender, System.EventArgs e) 
    { 
     if (Common.CheckDatabaseConnection()) 
     { 
      this.LiteralMachineName.Text = Environment.MachineName; 
     } 
     else 
     { 
      Response.ClearHeaders(); 
      Response.ClearContent(); 
      Response.Status = "503 ServiceUnavailable"; 
      Response.StatusCode = 503; 
      Response.StatusDescription= "An error has occurred"; 
      Response.Flush(); 
      throw new HttpException(503,string.Format("An internal error occurred in the Application on {0}",Environment.MachineName)); 
     } 
    } 
+0

Hola Paige. ¿Esto fue de un archivo .ashx o de un archivo regular .aspx? Intenté agregar los métodos clear/flush y no hizo diferencia. También intenté lanzar una nueva HttpException y obtuve algunas tonterías HTML no deseadas adicionales. Buen intento sin embargo. –

+0

Neil. Esto era de una página regular .aspx. Lamento haberme olvidado de que estabas trabajando con un archivo .ashx. –

+0

Funcionó perfectamente para mí, gracias. –

Cuestiones relacionadas