P29 自定义错误信息和错误报告
https://www.bilibili.com/video/BV1XJ411q7yy?p=29
如果自定义错误信息。如何报告错误信息
针对上一节讲的自定义属性
这里也可以使用ErrorMessage参数,但是想要这个ErrorMessage正常的返回给我们的用户。必须要改一下自定义的Attribute里面的代码
就是要把这块给改了
首先我们这里先写点内容
然后这里我们使用上面传入的ErrorMessage参数
很简单,有个属性就叫做ErrorMessage
折一下行
测试1
http://localhost:5000/api/companies/bbdee09c-089b-4d30-bece-44df5923716c/employees
body
{ "employeeNo": "0123456789", "firstName":"0123456789", "lastName":"三", "gender":1, "dateOfBirth":"1998-12-24" }
错误信息和报告
规定了错误信息的统一格式。原来我们只使用状态码的话,例如404 not found。这个状态码有时候不足以传达足够的信息。有时候对于我们人类的用户应该返回一个错误页面,上面有一些错误信息。
还可以识别出错误是属于哪个API
打开刚才的错误,首先是错误Type,我们打开这个链接地址。
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "|231fa898-4fceea08c8ad61ce.", "errors": { "EmployeeAddDto": [ "员工编号不可以等于名字" ] } }
https://tools.ietf.org/html/rfc7231#section-6.5.1
使用浏览器打开这个链接地址
6.5.1是 400 Bad Request
发生了一个或者是多个验证的错误。
状态码status是400。我们之前讲过,对于这种实体验证的错误最好是返回422.
traceId,日志里面可能会出现这个,用它可以查询日志具体的错误。
下面就是要自定义这个返回的错误。
startup自定义返回错误
我们对它进行设置。InvalidaModelStateResponseFactory它实际是一个action,这个action呢,我们可以对它进行设置。它会早Controller那个ModelState对象返回isvalid等于false的时候,它这个action就会被执行。
下面就写一下这个action,首先是一个参数,里面又是莱姆达表达式。
里面再new一个VlaidationProblemDetails 里面再传一个contex.ModelState
在ModelState里面初始化一些值
Type实际上我们可以自定义,
Type就是下面的这个type,链接地址的这个。目前默认返回的是一个链接地址,官方的文档。
我们可以自己实现一个链接,用户一旦发生错误,可以通过这个链接查找一些相关的内容。这里我们就先随便写一下。
状态码,我们应该返回的是422
422
instance通常就是请求路径。
增加traceId。用来做调用链的日志什么的
最后返回这个结果类型。把我们的problemDetails类型传进去。
然后它的格式需要设定一下。类型也是RC7807里面规定的。
services.AddControllers(setup=> { setup.ReturnHttpNotAcceptable = true; //setup.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()); }).AddXmlDataContractSerializerFormatters() .ConfigureApiBehaviorOptions(setup=> { setup.InvalidModelStateResponseFactory = context => { var problemDetails = new ValidationProblemDetails(context.ModelState) { Type = "http://www.baidu.com", Title = "有错误", Status=StatusCodes.Status422UnprocessableEntity, Instance=context.HttpContext.Request.Path }; problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier); return new UnprocessableEntityObjectResult(problemDetails) { ContentTypes = { "application/problem+json" } }; }; });
测试
其他验证方式
这是我们现在的验证方式。model类和验证信息规则都放在一个类面了。相当于是一个类干了两个活
FluentValidation把验证规格和类分开了。相当于争对某一个Model再创建一个FluentValidation的验证类。。分离的好处呢就是容易进行单元测试。
实际项目中,稍微复杂点的建议使用FluentValidation
FluentValidation官方
https://fluentvalidation.net/
在 ASP.NET Core 中使用 FluentValidation 进行验证
《Dotnet9》系列-FluentValidation在C# WPF中的应用
https://www.oschina.net/p/fluentvalidation?hmsr=aladdin1e1
结束