1.如果Content-Type是application/json,而POST和PUT的参数是[FromBody] string value,那么如果curl -d的值是'{"Name": "uuu"}'这种JSON字符串将会报错(暂不知为何),但是如果-d的值是'aas'这种普通字符串则不会有问题;
但是如果将上面的string value改成AClass value,然后AClass里有个Name的属性那么-d '{"Name": "uuu"}'也是不会有问题的(这是因为字符串'sss'本身就是对于string类型对象,就像33对于类型是int一样[FromBody] int value);
2.默认情况下WebApi对json请求体的属性名大小写不敏感,上诉的Name写成name也一样,哪怕AClass的属性是叫Name而非name;
3.WebApi里的IActionFilter的实现类就类似SpringMVC里的只有before和after的Aspect,它能够对参数进行一个修改,能够记录日志,但是不能像Interceptor一样进行一个逻辑判断发现不合要求就停止请求;
在IActionFilter里已经将Request.Body转换为了[FromBody]的参数的值,而由于Request.Body也是和Java一样只能被读取一次的,因此在IActionFilter里开启filterContext.HttpContext.Request.EnableBuffering();是无效的,流已经被读取完了;
IActionFilter对象的添加方式是通过
services.AddMvc(opt => { // 添加过滤器 opt.Filters.Add(typeof(ValidatorActionFilter)); })
4.可以不实现IActionFilter而是直接继承ActionFilterAttribute(ActionFilterAttribute同时兼具IActionFilter和IResultFilter,但是IExceptionFilter貌似没有对应的Attribute),这个类类似一个适配器,而且同时具有特性这个功能;
5.对于.net core2.2以上的WebApi的拦截器如果要实现不符合要求就pass掉可以用如下方法
public class AuthFilter : ActionFilterAttribute { public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!(context.ActionDescriptor is ControllerActionDescriptor)) { throw new ArgumentException(); } Console.WriteLine("开始啦啦啦啦啦" + "###" + ((ControllerActionDescriptor) context.ActionDescriptor).MethodInfo.CustomAttributes.Aggregate("", (a, b) => string.Join(",", a, b.AttributeType))); if (context.ActionDescriptor.DisplayName.Contains("Get")) { context.HttpContext.Response.Headers.Add("Content-Type", "application/json;charset=utf8"); await context.HttpContext.Response.WriteAsync("鉴权失败", Encoding.UTF8); } else {
// 只有Async的才能实现Around的功能 var resultContext = await next(); } Console.WriteLine("结束啦啦啦啦啦"); } }
6.可以在Startup里通过app来Use一个中间件,这个中间件就类似Tomcat的Filter:
app.UseHttpsRedirection(); app.Use(BarMiddleware); app.UseMvc(); } private static RequestDelegate BarMiddleware(RequestDelegate next) => async context => { Console.WriteLine("比IActionFilter最先的要先"); context.Request.EnableBuffering(); await next(context); Console.WriteLine("比IActionFilter最后的要后"); };
7..net core2.2里的WebApi的HttpContext.Request.Body的流本身就是可重复读取的,不需要再用HttpContext.Request.EnableBuffering();开启请求体缓存,不过主动读取Body之前要:HttpContext.Request.Body.Position = 0;然后用StreamReader来读取。