Конечно, просто переопределите привязку модели по умолчанию.
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