Можно ли регистрировать, когда запрос (JSON) преобразуется в объект в связывателе модели, а также в ответ?

Мне интересно, можно ли каким-то образом реализовать ведение журнала, когда запрос (в формате JSON) преобразуется в объект, а объект в ответ преобразуется в json (в привязке модели)? Я хочу избежать реализации ведения журнала в контроллерах, чтобы иметь более чистый код, если это возможно.

ИЗМЕНИТЬ:

Мне нужно регистрировать всю входящую и исходящую строку json.

Также я использую ASP.NET Web API 2.


person Henrik    schedule 21.05.2014    source источник
comment
Я не уверен, что вы имеете в виду, вы хотите зарегистрировать, что происходит в связывателе модели?   -  person user247702    schedule 21.05.2014
comment
Да, именно это я и имел в виду. Я хочу регистрировать входящие данные запроса, а также данные ответа... извините за мое объяснение.   -  person Henrik    schedule 21.05.2014


Ответы (1)


Конечно, просто переопределите привязку модели по умолчанию.

public class LoggingDataBinder : DefaultModelBinder
{

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
         var request = context.HttpContext.Request;
         //if you only want to deal with json requests
         if (request.ContentType == "application/json")
         {
              //can now access QueryString, URL, or InputStream
              using (var sr = new StreamReader(request.InputStream))
              {
                 var jsonData = sr.ReadToEnd();
                 LogMethod(jsonData);
              }    
         }
         return base.BindModel(controllerContext, bindingContext);
    }

} 

Затем в Global.asax.cs.Application_Start():

protected void Application_Start(Object sender, EventArgs e)
{
     ModelBinders.Binders.DefaultBinder = new LoggingModelBinder();
}

Вы можете настроить это различными способами (наличие этого пользовательского связывателя только для определенных типов, для определенных запросов, получение сведений из запроса для регистрации), но это удовлетворит ваш вопрос о том, как вести журнал, когда происходит привязка модели.

ИЗМЕНИТЬ

Чтобы обрабатывать ответы на журналирование, я бы предложил переопределить OnResultExecuted в вашем контроллере (или базовом контроллере) и сделать так:

protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
    //assuming this will be the type of all of your JSON data actions
    var json = filterContext.Result as JsonResult;
    if (json != null)
    {
         //assuming you haven't overriden the default serializer here,
         //otherwise may be inconsistent with what the client sees
         LogMethod(new JavaScriptSerializer().Serialize(json.Data));
    }
}

Вместо того, чтобы делать это на этом уровне, вы можете создать свой собственный ActionFilterAttribute и соответствующим образом декорировать свои контроллеры/методы действий (например, декорировать только методы действий, которые возвращают JsonResult). Вот старая статья из MSDN, что все равно направит вас на правильный путь к достижению этой цели.

EDIT 2 У меня нет опыта работы с Web API, но я считаю, что лучше всего реализовать обработчик сообщений:

public class JsonMessageLoggerHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        bool isJson = false;
        //not tested, you may have to play with this
        if (request.Content != null && request.Content.Headers.ContentType.MediaType == "application/json")
        {
            isJson = true;
            var requestText = await request.Content.ReadAsStringAsync();
            LogMethod(requestText);
        }
        // Call the inner handler.
        var response = await base.SendAsync(request, cancellationToken);

        //log the response
        if (isJson)
        {
            var responseText = await response.Content.ReadAsStringAsync();
            LogMethod(responseText);
        }

        return response;
    }
}

Затем подключите обработчик сообщений к классу WebApiConfig:

config.MessageHandlers.Add(new APITraceLogger());

Опять же, у меня нет опыта работы с Web API, поэтому вам, возможно, придется поиграть с этим (и, честно говоря, это может быть не лучший способ сделать это). Вот несколько ссылок для получения более подробной информации: SO Question и ASP.NET

person Sven Grosen    schedule 21.05.2014
comment
Я отредактировал свой пост. Мне нужно регистрировать всю входящую/исходящую строку json. Таким образом, я могу использовать одно и то же ведение журнала для всех типов запросов. - person Henrik; 21.05.2014
comment
@Henrik обновил ответ, чтобы включить способ получения данных json - person Sven Grosen; 21.05.2014
comment
Спасибо, я обрабатываю регистрацию ответа (данные json) тем же методом? - person Henrik; 21.05.2014
comment
@Henrik добавил подробности о регистрации ответа - person Sven Grosen; 21.05.2014
comment
Теперь, когда я тестировал, я заметил, что это используется для mvc, но мне нужно сделать это в веб-API 2. - person Henrik; 22.05.2014
comment
@ Хенрик Я добавил несколько заметок о веб-API, но, как я заявляю в этом редактировании, у меня нет опыта работы с веб-API, поэтому это может быть не лучший подход. - person Sven Grosen; 22.05.2014