2011-12-31 3 views
13

Я использую Elmah для регистрации исключений. Elmah отлично подходит для регистрации органов запроса, если запрос является запросом на основе формы (то есть Content-Type: application/x-www-form-urlencoded), но с запросами на основе JSON, где типом контента является application/json, тело запроса нигде не встречается в отчетах об ошибках. Кто-нибудь знает, где я могу найти этот орган запроса, чтобы я мог правильно диагностировать мои исключения?Elmah: Как получить тело запроса JSON HTTP из отчета об ошибке

UPDATE: 2012-01-03

В разъяснении на то, что я имею в виду запросов на основе JSON, вот запрос пример сырой HTTP с JSON в теле запроса:

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

{"city":"Vancouver"} 
+0

Что вы с запросами на основе JSON? Получают ли они через GET или POST? Если вы введете страницу сведений и нажмите «Исходные/исходные данные в XML», вы можете увидеть там тело? – alexn

+0

@alexn, запросы отправляются через PUT и POST. Исходные данные в XML не отображают тело запроса для запросов на основе JSON. Пожалуйста, ознакомьтесь с моей обновленной информацией, приведенной выше, для уточнения того, что я имею в виду под запросами JSON. –

ответ

17

Elmah пока только регистрирует контекст или информацию, которая является периферийной для запроса, и которая может быть удобно захвачена стандартным способом. Формы, возможно, являются особым обращением, потому что ASP.NET уже выполняет дешифровку и запоминает запрашивает объекты, когда тип MIME равен application/x-www-form-urlencoded. С другой стороны, запросы JSON являются пролематическими, поскольку во время возникновения исключения входной поток (HttpRequest.InputStream) может быть частично или полностью потреблен декодером JSON. ELMAH не смог бы получить вторую трещину с целью регистрации. Поэтому вам нужно будет убедиться, что вы буферизируете входной поток или текст, прежде чем передавать его через любой декодер JSON и спрячьте его где-нибудь, как HttpContext.Items. Затем вы можете попытаться восстановить буферизованные данные и attach it to an outgoing mail at the time of an error. В настоящее время ELMAH не поддерживает прикрепление произвольных данных к зарегистрированной ошибке. Однако есть ErrorLogModule, который имеет событие Logged и который отправляет идентификатор зарегистрированной ошибки. Это можно использовать для хранения входных данных в другом месте (возможно, в другой таблице, если вы используете базовую базу данных для журналов ошибок), но привяжите ее к зарегистрированной ошибке, поддерживая ассоциацию через Id.

+0

Спасибо Атиф за подробный ответ. Что касается опции исходящей почты (т. Е. Внутри ErrorMail_Mailing), у меня нет доступа к HttpContext, поэтому я не могу получить доступ к HttpContext.Items. Если бы я мог получить доступ к HttpContext, я могу попытаться восстановить тело запроса из HttpRequest.InputStream, если он все еще доступен. Возможно ли получить доступ к HttpContext из ErrorMail_Mailing? –

+0

У вас должен быть доступ к свойству ['Context'] (http://msdn.microsoft.com/en-us/library/system.web.httpapplication.context.aspx) внутри обработчика событий. Он наследуется от ['HttpApplication'] (http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx) с помощью' Global.asax'. Попробуйте «this.Context» или просто введите «this» then period (.), И он должен появиться в IntelliSense в среде IDE. –

+0

this.Context is null и this.Request выдает исключение, потому что оно больше не доступно. HttpContext.Ток также нулевой. Кажется, что ErrorMail_Mailing вызывается после отправки ответа. –

1

В дополнение к ответу Атифа здесь есть способ: add additional details to ELMAH log, вручную выбросив новое исключение. Это не особенно элегантно, но, похоже, это делает работу!

мне было бы интересно услышать комментарии от самого человека ...

+0

Интересно. Благодарю. –

4

первой установки NuGet пакет: Newtonsoft.Json

install-package Newtonsoft.Json 

затем:

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)); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^