是否可以记录请求(JSON)何时被转换为模型绑定器中的对象以及响应

本文关键字:绑定 模型 对象 响应 请求 记录 JSON 是否 何时 转换 | 更新日期: 2023-09-27 18:04:22

我想知道当请求(JSON格式)转换为对象和对象在响应中转换为JSON时,是否有可能实现日志记录(在模型绑定中)?如果可能的话,我想避免在控制器中实现日志记录以获得更干净的代码。

编辑:

我需要记录整个传入和传出的json字符串。

我也使用ASP。. NET Web api 2

是否可以记录请求(JSON)何时被转换为模型绑定器中的对象以及响应

当然,只需覆盖默认的模型绑定器。

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的旧文章,它仍然会让你走上正确的道路。

编辑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问题和ASP。净