asp.net webapi post 原文获取
今天在和接口调用方调试webapi接口时,发现post方法的参数对象总是为空,各种原因之下,我想把post的字符串log下来,但是始终无法获取body字符串。经过查阅找到解决方法,在此备忘。
[HttpPost] public AjaxResult Post(dynamic JsonObject) { // ... }
此action期待调用端post的body是一个json格式,但是如果调用端传的格式有误,那么这里拿到的JsonObject对象为空。那程序如何判断是真的为空,还是因为格式错误而为空的?
在action里面使用这句可以读出body的内容:
Request.Content.ReadAsStringAsync().Result;
但是是有条件的,就是这个action的参数不能是dynamic,否则这句读出的一直都是空值。其中的原因还需要进一步解读webapi的原理才能知道
[HttpPost] public AjaxResult Post() {
// 参数为空的action就可以出来body字符串,如果是dynamic类型的参数,则无法读取
string body = Request.Content.ReadAsStringAsync().Result;
}
在读出body字符串之后,可以调用JsonConvert反序列化为JObject进行进一步的操作,如果json格式有误,则在这一步会抛出异常,
我们在ExceptionFilterAttribute里面进行统一的捕获并记录错误的json,方便问题排查。
public class ApiExceptionFilterAttribute : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext actionExecutedContext) { string controllerName = actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerName; string actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName; string logContent = string.Format("{0}\n请求目标:{1}.{2}\n请求地址:{3}", actionExecutedContext.Exception.Message, controllerName, actionName, actionExecutedContext.Request.RequestUri.ToString()); if (actionExecutedContext.Exception is Newtonsoft.Json.JsonReaderException) { logContent = string.Concat(logContent, $"\nJson原文:{actionExecutedContext.Request.Content.ReadAsStringAsync().Result}"); } // 记录Log ... base.OnException(actionExecutedContext); } }