2012-04-23 52 views
11

Comenzaré con, sí, hemos creado y estamos utilizando un filtro de excepción que hereda de ExceptionFilterAttribute. Se registra en el inicio de la configuración al inicio de la aplicación justo después de nuestro filtro de identidad y funciona prácticamente como se esperaba si ocurre un error en algún lugar dentro de nuestra API.Gestión de excepciones ASP.NET MVC Web API

Dicho esto, estoy buscando una forma de manejar los errores que ocurren antes de que llegue a la API.

Razonamiento: Nunca queremos devolver un error de YSOD y/o IIS HTML. SIEMPRE queremos presionar un filtro/controlador de excepciones personalizado para que podamos manejar el registro correctamente y devolver una respuesta JSON al usuario.

En este momento, al usar Fiddler para realizar una solicitud, puedo adjuntarme al proceso w3wp.exe y ver que la solicitud apriete el método Application_BeginRequest en global.asax. Después de eso, solo devuelve una respuesta de 500. Nunca se rompe en el código con una excepción o golpea cualquiera de mis puntos de quiebre después de eso. Parece que está devolviendo un error de IIS. Nunca queremos que esto suceda. Necesitamos la capacidad de detectar todas estas excepciones de "bajo nivel", registrarlas y devolver algo significativo para el usuario.

¿Hay algo que podamos hacer para manejar errores antes, lo que parece estar afectando al código ASP.NET MVC Web API?

+0

Esto se siente mal de alguna manera. ¿Estás arrojando excepciones en alguna biblioteca? ¿Por qué no simplemente atrapar la excepción en el controlador y devolver una vista de error de su elección? –

+1

Esto está utilizando ASP.NET MVC Web API, por lo que no estamos devolviendo vistas desde los controladores. Devolvemos respuestas JSON/XML. También menciono en mi pregunta que necesito una forma de manejar excepciones ANTES de que lleguen a los controladores. En este momento tenemos un ExceptionFilter que detecta excepciones en cualquier lugar una vez que estamos dentro del controlador, así no tenemos que tener try/catch en cada acción. – phreak3eb

+0

No creo que entiendo completamente tu pregunta. ¿Qué tipo de errores estás tratando de atrapar exactamente? – cecilphillip

Respuesta

4

Aunque me gusta la respuesta de Darin, no funciona en nuestro caso ya que el marco ASP.NET MVC Web API suprime/maneja las excepciones internamente y no vuelve a lanzar para ejecutar el método Application_Error en Global.asax. Nuestra solución es esto.

que acabó creando un DelegatingHandler encargo de este modo:

public class PrincipalHandler : DelegatingHandler 
{ 
    protected const string PrincipalKey = "MS_UserPrincipal"; 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     setAnonymousPrincipal(); 

     request = InitializeIdentity(request); 

     return base.SendAsync(request, cancellationToken) 
      .ContinueWith(r => 
           { 
            // inspect result for status code and handle accordingly 
            return r.Result; 
           }); 
    } 
} 

entonces insertarse en la HttpConfiguration para asegurarse de que es el primer/último manipulador de ser golpeado. La manera en que los manejadores trabajan en la API web es de forma jerárquica. Por lo tanto, el primer controlador en ser golpeado por solicitud será el último controlador en recibir la respuesta. Al menos esto es lo que entiendo, alguien puede corregirme si me equivoco.

public static void ConfigureApis(HttpConfiguration config) 
{ 
    config.MessageHandlers.Insert(0, new PrincipalHandler()); 
} 

Al utilizar este enfoque ahora podemos inspeccionar cada resultado que se devuelve en cualquier respuesta de la API web y los controladores. Esto nos permite manejar cualquier registro que pueda necesitarse como resultado de que algo no se devuelve como esperamos. Ahora también podemos alterar el contenido de la respuesta que vuelve para que IIS no inserte ninguna página de error HTML predeterminada si ve ciertos códigos de estado HTTP.

El único problema que tengo con esto, y espero que lo cambien en una próxima versión de la API web, es que no están enviando la excepción a la Tarea que se devuelve desde base.SendAsync () Por lo tanto, la única información que debemos conocer es el código de estado HTTP y hacemos todo lo posible para dar una respuesta razonable o probable al consumidor.

+0

Para cualquiera que esté buscando documentación sobre el cableado de la llamada a 'config.MessageHandlers.Insert()', está disponible [en la documentación de WebAPI] (http://www.asp.net/web-api/overview/working-with -http/http-message-handlers). –

+1

Si desea un controlador de error global en la API web con la información de excepción completa disponible, vote esta característica en http://aspnetwebstack.codeplex.com/workitem/1001 –

+0

Esto también parece una variación útil: http: // blog.codeishard.net/2013/02/09/webapi-and-the-behavior-of-exceptions-and-an-alternative-configurable-way-to-deal/ – CrazyPyro