[英]Is there any way to add error code to ModelState error
我正在寻找一种将错误代码与错误消息一起添加到ModelState
的方法。 例如
ModelState.AddModelError("ErrorKey", new { Code = 4001, Message = "Some error message" });
对于一些错误的请求,客户端应该执行操作,比较错误消息不是做出决定的理想解决方案。 ModelState.AddModelError
方法只接受两个参数,一个错误键和一个消息。 有没有办法实现这个或类似的东西?
不,当您尝试执行以下操作时,没有办法在您的代码中实现您正在寻找的东西:
return BadRequest(ModelState);
您将收到400 bad request
响应,其中包含您已添加的消息(如您所见,错误代码已在此处显示)。 因此,在您的情况下,既没有用法也没有添加错误代码的方法。
我找到了一种将错误代码添加到ValidationProblemDetails
的方法:
public class CustomValidationProblemDetails : ValidationProblemDetails
{
public CustomValidationProblemDetails()
{
}
[JsonPropertyName("errors")]
public new IEnumerable<ValidationError> Errors { get; } = new List<ValidationError>();
}
ValidationProblemDetails
有一个Error属性,它是IDictionary<string, string[]>
并将这个属性替换为我们的版本以添加代码错误。
public class ValidationError
{
public int Code { get; set; }
public string Message { get; set; }
}
ValidationProblemDetails
的构造函数接受 ModelStateDictionary 并需要将其转换为ValidationError
列表:
public CustomValidationProblemDetails(IEnumerable<ValidationError> errors)
{
Errors = errors;
}
public CustomValidationProblemDetails(ModelStateDictionary modelState)
{
Errors = ConvertModelStateErrorsToValidationErrors(modelState);
}
private List<ValidationError> ConvertModelStateErrorsToValidationErrors(ModelStateDictionary modelStateDictionary)
{
List<ValidationError> validationErrors = new();
foreach (var keyModelStatePair in modelStateDictionary)
{
var errors = keyModelStatePair.Value.Errors;
switch (errors.Count)
{
case 0:
continue;
case 1:
validationErrors.Add(new ValidationError { Code = 100, Message = errors[0].ErrorMessage });
break;
default:
var errorMessage = string.Join(Environment.NewLine, errors.Select(e => e.ErrorMessage));
validationErrors.Add(new ValidationError { Message = errorMessage });
break;
}
}
return validationErrors;
}
当我们想要返回错误的请求响应时,创建自定义 ProblemDetailsFactory 以创建 CustomValidationProblemDetails:
public class CustomProblemDetailsFactory : ProblemDetailsFactory
{
public override ProblemDetails CreateProblemDetails(HttpContext httpContext, int? statusCode = null, string title = null,
string type = null, string detail = null, string instance = null)
{
var problemDetails = new ProblemDetails
{
Status = statusCode,
Title = title,
Type = type,
Detail = detail,
Instance = instance,
};
return problemDetails;
}
public override ValidationProblemDetails CreateValidationProblemDetails(HttpContext httpContext,
ModelStateDictionary modelStateDictionary, int? statusCode = null, string title = null, string type = null,
string detail = null, string instance = null)
{
statusCode ??= 400;
type ??= "https://tools.ietf.org/html/rfc7231#section-6.5.1";
instance ??= httpContext.Request.Path;
var problemDetails = new CustomValidationProblemDetails(modelStateDictionary)
{
Status = statusCode,
Type = type,
Instance = instance
};
if (title != null)
{
// For validation problem details, don't overwrite the default title with null.
problemDetails.Title = title;
}
var traceId = Activity.Current?.Id ?? httpContext?.TraceIdentifier;
if (traceId != null)
{
problemDetails.Extensions["traceId"] = traceId;
}
return problemDetails;
}
}
最后注册工厂:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddTransient<ProblemDetailsFactory, CustomProblemDetailsFactory>();
}
阅读扩展问题详细信息 - 将错误代码添加到 ValidationProblemDetails以获取更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.