Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ASP.NET核心:防止针对单个操作的自动HTTP 400响应_Asp.net_Asp.net Core - Fatal编程技术网

ASP.NET核心:防止针对单个操作的自动HTTP 400响应

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

我喜欢ASP.NET Core 2.1的新功能,它在大多数情况下运行得非常好

然而,在一个动作中,我需要在验证有效负载之前做一些预处理。我有一个自定义验证器,它需要模型中的两个值来执行验证。其中一个值位于路径中,因此我希望在模型上从路径设置该值,然后进行验证

我不想关闭以下所有操作的功能:

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();
    }
}