如何使“发生一个或多个验证错误”引发异常?

AnK*_*ing 16 asp.net-core asp.net-core-3.1

我正在 Core 3.1 上运行 WebAPI,我的端点之一(JSON 除外)的模型具有带有[Required]属性的字段,如下所示:

public class Vendor
{
        public int ID { get; set; }
        [Required(ErrorMessage = "UID is required")]   <<<------ required attribute
        public string UID { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我在不设置 UID 的情况下调用此端点时,我会按预期获得以下输出:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|7ced8b82-4aa34d65daa99a12.",
    "errors": {
        "Vendor.UID": [
            "UID is required"
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

尽管此输出信息丰富且清晰,但它与我的 API 通过 ExceptionFilter 生成的其他错误输出不一致。有什么方法可以将此错误路由到异常过滤器吗?

这是我的 Startup.cs:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            Common.Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
            services.AddMvc().AddXmlDataContractSerializerFormatters();
            services.AddMvc().AddMvcOptions(options =>
            {
                options.EnableEndpointRouting = false;
            });
            services.AddMvcCore(options => options.OutputFormatters.Add(new XmlSerializerOutputFormatter()));
            services.AddOptions();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
        {

            //Middleware for exception filtering
            app.UseMiddleware<ErrorHandlingMiddleware>(new ErrorHandlingMiddlewareOptions { logger = logger });

            app.UseStaticFiles();            

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute("EndpointNotFound", "{*url}", new { controller = "Error", action = "EndpointNotFound" });
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)

moh*_*chi 6

您可以在 mvc 服务或控制器服务中添加过滤器

该过滤器返回错误请求

services.AddControllers(option =>
{
             option.Filters.Add<ValidationFilter>();
});
Run Code Online (Sandbox Code Playgroud)

要创建过滤器,您可以添加此类,也可以根据需要自定义此过滤器

public class ValidationFilter : IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            //before contrller

            if(!context.ModelState.IsValid)
            {
                var errorsInModelState = context.ModelState
                    .Where(x => x.Value.Errors.Count > 0)
                    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors.Select(x => x.ErrorMessage).ToArray());

                var errorResponse = new ErrorResponse();

                foreach (var error in errorsInModelState)
                {
                    foreach (var subError in error.Value)
                    {
                        var errorModel = new ErrorModel
                        {
                            FieldName = error.Key,
                            Message = subError
                        };

                        errorResponse.Error.Add(errorModel);
                    }

                    context.Result = new BadRequestObjectResult(errorResponse);
                    return;
                }

                await next();

                //after controller  
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我已经像这样创建了错误模型

public class ErrorModel
    {
        public string FieldName { get; set; }
        public string Message { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

和错误响应如下

public class ErrorResponse
    {
        public List<ErrorModel> Error { get; set; } = new List<ErrorModel>();
        public bool Successful { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)


Sán*_*ics 1

为了实现此功能,您需要实现此问题中描述的您自己的模型验证器:Web API 中的模型验证 - 异常在没有 throw 语句的情况下抛出?