ASP.NET核心:防止针对单个操作的自动HTTP 400响应
我喜欢ASP.NET Core 2.1的新功能,它在大多数情况下运行得非常好 然而,在一个动作中,我需要在验证有效负载之前做一些预处理。我有一个自定义验证器,它需要模型中的两个值来执行验证。其中一个值位于路径中,因此我希望在模型上从路径设置该值,然后进行验证 我不想关闭以下所有操作的功能:ASP.NET核心:防止针对单个操作的自动HTTP 400响应,asp.net,asp.net-core,Asp.net,Asp.net Core,我喜欢ASP.NET Core 2.1的新功能,它在大多数情况下运行得非常好 然而,在一个动作中,我需要在验证有效负载之前做一些预处理。我有一个自定义验证器,它需要模型中的两个值来执行验证。其中一个值位于路径中,因此我希望在模型上从路径设置该值,然后进行验证 我不想关闭以下所有操作的功能: public void ConfigureServices(IServiceCollection services) { services.Configure<ApiBehaviorOption
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
}
public void配置服务(IServiceCollection服务)
{
服务。配置这可能通过为您的特定案例实现您自己的验证器来解决。文档中对其进行了详细介绍
这可能是一个自定义模型绑定器,用于创建模型,并在验证之前完成所有预处理。您可以使用属性根据actionContext
详细信息处理特定情况:
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = actionContext =>
{
// Do what you need here for specific cases with `actionContext`
// I believe you can cehck the action attributes
// if you'd like to make mark / handle specific cases by action attributes.
return new BadRequestObjectResult(context.ModelState);
}
});
services.Configure(选项=>
{
options.InvalidModelStateResponseFactory=actionContext=>
{
//在“actionContext”的特定案例中执行您需要的操作
//我相信你能切克动作属性
//如果您希望通过操作属性标记/处理特定案例。
返回新的BadRequestObjectResult(context.ModelState);
}
});
我收到了微软的回复-
下面这句话很有魅力
[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : Attribute, IActionModelConvention
{
public void Apply(ActionModel action)
{
for (var i = 0; i < action.Filters.Count; i++)
{
if (action.Filters[i] is ModelStateInvalidFilter)
{
action.Filters.RemoveAt(i);
break;
}
}
}
}
更新:您可以在Startup.cs中的ConfigureServices中使用以下代码:
services.Configure<ApiBehaviorOptions>(apiBehaviorOptions => {
apiBehaviorOptions.SuppressModelStateInvalidFilter = true;
});
services.Configure(apiBehaviorOptions=>{
apiBehaviorOptions.SuppressModelStateInvalidFilter=true;
});
根据Simon Vane的回答,我必须修改ASP.Net Core 2.2的属性,如下所示:
/// <summary>
/// Suppresses the default ApiController behaviour of automatically creating error 400 responses
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : Attribute, IActionModelConvention {
private static readonly Type ModelStateInvalidFilterFactory = typeof(ModelStateInvalidFilter).Assembly.GetType("Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilterFactory");
public void Apply(ActionModel action) {
for (var i = 0; i < action.Filters.Count; i++) {
if (action.Filters[i] is ModelStateInvalidFilter || action.Filters[i].GetType() == ModelStateInvalidFilterFactory) {
action.Filters.RemoveAt(i);
break;
}
}
}
}
//
///抑制自动创建错误400响应的默认ApiController行为
///
[AttributeUsage(AttributeTargets.Method)]
公共类SuppressModelStateInvalidFilterAttribute:属性,IActionModelConvention{
私有静态只读类型ModelStateInvalidFilterFactory=typeof(ModelStateInvalidFilter).Assembly.GetType(“Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilterFactory”);
公共无效应用(ActionModel action){
对于(变量i=0;i
我遇到了类似的问题,并提出了这个解决方案
public class SuppressModelStateInvalidFilterAttribute : ActionFilterAttribute
{
public SuppressModelStateInvalidFilterAttribute()
{
Order = -2500;
}
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
context.ModelState.Clear();
return next.Invoke();
}
}
好的,如果您对添加第三方库没意见,那么有一个叫做fluent validation的工具,它可以帮助您验证复杂的模型类型,并且还支持“预验证”逻辑。这可能会有帮助。这是文档:非常感谢这些建议,我对此寄予厚望,但这并不能解决我的问题。我需要进入控制器操作。只是为了了解一些额外的信息,我为我的问题添加了一个更新。我正在实现一个自定义验证器。我只需要从路径中获取一个值并设置在验证之前,请在模型上添加它。我认为您的自定义活页夹建议可能是一种方法。我会尝试一下。谢谢。这应该是操作。筛选器[I]是ModelStateInvalidFilterFactory,但它是内部的;/。
/// <summary>
/// Suppresses the default ApiController behaviour of automatically creating error 400 responses
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : Attribute, IActionModelConvention {
private static readonly Type ModelStateInvalidFilterFactory = typeof(ModelStateInvalidFilter).Assembly.GetType("Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilterFactory");
public void Apply(ActionModel action) {
for (var i = 0; i < action.Filters.Count; i++) {
if (action.Filters[i] is ModelStateInvalidFilter || action.Filters[i].GetType() == ModelStateInvalidFilterFactory) {
action.Filters.RemoveAt(i);
break;
}
}
}
}
public class SuppressModelStateInvalidFilterAttribute : ActionFilterAttribute
{
public SuppressModelStateInvalidFilterAttribute()
{
Order = -2500;
}
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
context.ModelState.Clear();
return next.Invoke();
}
}