2011-12-31 8 views
13

Estoy usando Elmah para registrar excepciones. Elmah es excelente para registrar cuerpos de solicitud si la solicitud es una solicitud basada en el Formulario (es decir, Content-Type: application/x-www-form-urlencoded), pero con solicitudes basadas en JSON donde el tipo de contenido es application/json, el cuerpo de la solicitud no se encuentra en los informes de errores. ¿Alguien sabe dónde puedo encontrar este cuerpo de solicitud para poder diagnosticar mis excepciones correctamente?Elmah: Cómo obtener el cuerpo de solicitud de JSON HTTP del informe de error

ACTUALIZACIÓN: 2012-01-03

Como aclaración sobre lo que quiero decir con las solicitudes basadas JSON, he aquí un ejemplo de solicitud HTTP con prima JSON como el cuerpo de la petición:

PUT http://mycompany.com/api/v1.0/me HTTP/1.1 
Host: mycompany.com 
Content-Length: 20 
Content-Type: application/json 

{"city":"Vancouver"} 
+0

Lo que hace que significa con solicitudes basadas en JSON? ¿Están recibiendo a través de GET o POST? Si ingresa a una página de detalles y hace clic en "Raw/Source data in XML", ¿puede ver el cuerpo allí? – alexn

+0

@alexn, las solicitudes se envían a través de PUT y POST. Los datos en bruto/origen en XML no muestran el cuerpo de la solicitud para las solicitudes basadas en JSON. Consulte mi información actualizada más arriba para obtener una aclaración sobre lo que quiero decir con solicitudes basadas en JSON. –

Respuesta

17

ELMAH hasta ahora solo registra el contexto o la información que es periférica a la solicitud y que se puede capturar convenientemente de forma estándar. Los formularios son posiblemente un tratamiento especial porque ASP.NET ya hace el trabajo de decodificación y memorizando entidades de solicitud cuando el tipo MIME es application/x-www-form-urlencoded. Las solicitudes JSON, por otro lado, son prolemáticas porque en el momento en que ocurre una excepción, el decodificador JSON pudo haber consumido total o parcialmente el flujo de entrada (HttpRequest.InputStream). ELMAH no podría obtener una segunda grieta con el propósito de iniciar sesión. Por lo tanto, deberá asegurarse de almacenar en búfer el flujo de entrada o el texto antes de pasarlo a través de cualquier decodificador JSON y guardarlo en algún lugar como HttpContext.Items. A continuación, puede tratar de recuperar los datos almacenados en el búfer y attach it to an outgoing mail at the time of an error. ELMAH actualmente no admite adjuntar datos arbitrarios a un error registrado. Sin embargo, existe el ErrorLogModule que tiene un evento Logged y que proporciona el ID del error registrado. Esto podría usarse para almacenar los datos de entrada en otro lugar (quizás en otra tabla si está utilizando una base de datos de back-end para los registros de errores) pero volver a vincularlo con el error registrado manteniendo una asociación a través del Id.

+0

Gracias a Atif por su respuesta detallada. En cuanto a la opción de correo saliente (es decir, dentro de ErrorMail_Mailing), no tengo acceso al HttpContext, por lo que no puedo acceder a HttpContext.Items. Si pudiera acceder a HttpContext, entonces puedo intentar recuperar el cuerpo de la solicitud desde HttpRequest.InputStream si aún está disponible. ¿Es posible acceder a HttpContext desde ErrorMail_Mailing? –

+0

Debería tener acceso a la propiedad ['Context'] (http://msdn.microsoft.com/en-us/library/system.web.httpapplication.context.aspx) dentro del controlador de eventos. Se hereda de ['HttpApplication'] (http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx) por' Global.asax'. Pruebe 'this.Context' o simplemente escriba' this' then period (.) Y debería aparecer en IntelliSense en el IDE. –

+0

this.Context es nulo y this.Request arroja una excepción porque ya no está disponible. HttpContext.La corriente también es nula. Parece que se llama a ErrorMail_Mailing después de que se envía la respuesta. –

1

Además de la respuesta de Atif aquí, hay una manera de add additional details to ELMAH log lanzando manualmente una nueva excepción. ¡No es particularmente elegante, pero parece hacer el trabajo!

estaría interesado en escuchar cualquier comentario del hombre mismo ...

+0

Interesante. Gracias. –

4

instalar primero el paquete Nuget: Newtonsoft.Json

install-package Newtonsoft.Json 

a continuación:

public override void OnException(HttpActionExecutedContext filterContext) 
     { 
    var message = new StringBuilder(); 
      foreach (var param in filterContext.ActionContext.ActionArguments) 
      { 
       message.Append(string.Format("{0}:{1}\r\n", param.Key, Newtonsoft.Json.JsonConvert.SerializeObject(param.Value))); 
      } 
      var ex = new Exception(message.ToString(), filterContext.Exception); 
      var context = HttpContext.Current; 
      ErrorLog.GetDefault(context).Log(new Error(ex, context)); 
} 
Cuestiones relacionadas