自定义内容类型验证过滤器?
Custom Content-Type validation filter?
我想实现自定义内容类型验证过滤器,以便可以提供针对 415 不支持媒体类型的自定义错误模型。
像这样:
public class ValidateContentTypeFilterAttribute : ActionFilterAttribute
{
private const string JsonMimeType = "application/json";
public override void OnActionExecuting(ActionExecutingContext context)
{
string requestMethod = context.HttpContext.Request.Method.ToUpper();
if (requestMethod == WebRequestMethods.Http.Post || requestMethod == WebRequestMethods.Http.Put)
{
if (request.ContentType != JsonMimeType)
{
// "Unsupported Media Type" HTTP result.
context.Result = new HttpUnsupportedMediaTypeResult();
return;
}
}
}
}
问题是 MVC 管道在执行任何自定义过滤器之前似乎 "catching" 不受支持或无效的 Content-Type 值。即使 'application/xml' 内容类型也会被拒绝。
这个要配置在哪里?
我的 MVC 配置仅包含以下内容:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Include;
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
options.SerializerSettings.Converters.Add(new SquidJsonConverter());
})
.AddMvcOptions(options =>
{
options.Filters.Add(typeof(ValidateAntiForgeryTokenAttribute));
options.Filters.Add(typeof(ValidateContentTypeFilterAttribute));
options.Filters.Add(typeof(ValidateAcceptFilterAttribute));
options.Filters.Add(typeof(ValidateModelFilterAttribute));
});
...
}
对于您要在此处实现的目标,操作过滤器在处理管道中为时已晚。
"incoming" 请求的过滤器执行顺序如下:
- 授权过滤器的
OnAuthorization..
方法调用
- 资源过滤器的
OnResourceExecuting..
方法调用模型
- 发生模型绑定(这是内容类型检查的地方
制作)
- 操作过滤器的
OnActionExecuting..
方法调用
- 动作执行发生
您可以改为创建资源过滤器。一个例子:
public class CustomResourceFilter : IResourceFilter
{
private readonly string jsonMediaType = "application/json";
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
if (context.HttpContext.Request.Method == "PUT" || context.HttpContext.Request.Method == "POST")
{
if (!string.Equals(
MediaTypeHeaderValue.Parse(context.HttpContext.Request.ContentType).MediaType,
jsonMediaType,
StringComparison.OrdinalIgnoreCase))
{
context.Result = new JsonResult(new { Error = "An error message here" }) { StatusCode = 415 };
}
}
}
}
如果您想修改所有类型的 UnsupportedMediaTypeResult
响应,那么您可以改为编写结果过滤器。
传出响应的过滤器管道是:
- 操作过滤器的
OnActionExecuted...
方法调用
- 结果过滤器'
OnResultExecuting..
方法调用
- 结果过滤器'
OnResultExecuted..
方法调用
- 资源过滤器的
OnResourceExecuted..
方法调用
带有结果过滤器的示例:
public class CustomResultFilter : ResultFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
var result = context.Result as UnsupportedMediaTypeResult;
if (result != null)
{
context.Result = new JsonResult(new { Error = "An error message here" }) { StatusCode = 415 };
}
}
}
我想实现自定义内容类型验证过滤器,以便可以提供针对 415 不支持媒体类型的自定义错误模型。
像这样:
public class ValidateContentTypeFilterAttribute : ActionFilterAttribute
{
private const string JsonMimeType = "application/json";
public override void OnActionExecuting(ActionExecutingContext context)
{
string requestMethod = context.HttpContext.Request.Method.ToUpper();
if (requestMethod == WebRequestMethods.Http.Post || requestMethod == WebRequestMethods.Http.Put)
{
if (request.ContentType != JsonMimeType)
{
// "Unsupported Media Type" HTTP result.
context.Result = new HttpUnsupportedMediaTypeResult();
return;
}
}
}
}
问题是 MVC 管道在执行任何自定义过滤器之前似乎 "catching" 不受支持或无效的 Content-Type 值。即使 'application/xml' 内容类型也会被拒绝。
这个要配置在哪里?
我的 MVC 配置仅包含以下内容:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Include;
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
options.SerializerSettings.Converters.Add(new SquidJsonConverter());
})
.AddMvcOptions(options =>
{
options.Filters.Add(typeof(ValidateAntiForgeryTokenAttribute));
options.Filters.Add(typeof(ValidateContentTypeFilterAttribute));
options.Filters.Add(typeof(ValidateAcceptFilterAttribute));
options.Filters.Add(typeof(ValidateModelFilterAttribute));
});
...
}
对于您要在此处实现的目标,操作过滤器在处理管道中为时已晚。
"incoming" 请求的过滤器执行顺序如下:
- 授权过滤器的
OnAuthorization..
方法调用 - 资源过滤器的
OnResourceExecuting..
方法调用模型 - 发生模型绑定(这是内容类型检查的地方 制作)
- 操作过滤器的
OnActionExecuting..
方法调用 - 动作执行发生
您可以改为创建资源过滤器。一个例子:
public class CustomResourceFilter : IResourceFilter
{
private readonly string jsonMediaType = "application/json";
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
if (context.HttpContext.Request.Method == "PUT" || context.HttpContext.Request.Method == "POST")
{
if (!string.Equals(
MediaTypeHeaderValue.Parse(context.HttpContext.Request.ContentType).MediaType,
jsonMediaType,
StringComparison.OrdinalIgnoreCase))
{
context.Result = new JsonResult(new { Error = "An error message here" }) { StatusCode = 415 };
}
}
}
}
如果您想修改所有类型的 UnsupportedMediaTypeResult
响应,那么您可以改为编写结果过滤器。
传出响应的过滤器管道是:
- 操作过滤器的
OnActionExecuted...
方法调用 - 结果过滤器'
OnResultExecuting..
方法调用 - 结果过滤器'
OnResultExecuted..
方法调用 - 资源过滤器的
OnResourceExecuted..
方法调用
带有结果过滤器的示例:
public class CustomResultFilter : ResultFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
var result = context.Result as UnsupportedMediaTypeResult;
if (result != null)
{
context.Result = new JsonResult(new { Error = "An error message here" }) { StatusCode = 415 };
}
}
}