viv*_*una 6 c# asp.net-web-api asp.net-core asp.net-core-webapi .net-5
我需要使用ProblemDetails来验证错误。它按预期工作。但这里有一个大问题,我必须在所有操作方法中编写类似的代码,我认为这不是一个好主意。
public async Task<ActionResult<SampleResponse>> Post([FromBody] SampleRequest getRateApiRequest)
{
try
{
if (ModelState.IsValid == false)
{
ProblemDetails problemDetails = new ProblemDetails();
problemDetails.Detail = "Detail";
problemDetails.Instance = "Instance";
problemDetails.Status = StatusCodes.Status400BadRequest;
problemDetails.Title = "Title";
problemDetails.Type = "Type";
List<FieldCodeMessage> codeMessages = new List<FieldCodeMessage>();
foreach (var modelState in ModelState)
{
if (modelState.Value.ValidationState == Microsoft.AspNetCore.Mvc.ModelBinding.ModelValidationState.Invalid)
{
MemberInfo property = typeof(TradeBookingRequestAPI).GetProperty(modelState.Key);
var attribute = property.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().Single();
string displayName = attribute.DisplayName;
switch (modelState.Key)
{
case "Property1":
codeMessages.Add(new FieldCodeMessage(field: displayName, code: "01", message: modelState.Value.Errors.Select(a => a.ErrorMessage).FirstOrDefault()));
break;
case "Property2":
codeMessages.Add(new FieldCodeMessage(field: displayName, code: "02", message: modelState.Value.Errors.Select(a => a.ErrorMessage).FirstOrDefault()));
break;
case "Property3":
codeMessages.Add(new FieldCodeMessage(field: displayName, code: "03", message: modelState.Value.Errors.Select(a => a.ErrorMessage).FirstOrDefault()));
break;
case "Property4":
codeMessages.Add(new FieldCodeMessage(field: displayName, code: "04", message: modelState.Value.Errors.Select(a => a.ErrorMessage).FirstOrDefault()));
break;
case "Property5":
codeMessages.Add(new FieldCodeMessage(field: displayName, code: "05", message: modelState.Value.Errors.Select(a => a.ErrorMessage).FirstOrDefault()));
break;
case "Property6":
codeMessages.Add(new FieldCodeMessage(field: displayName, code: "06", message: modelState.Value.Errors.Select(a => a.ErrorMessage).FirstOrDefault()));
break;
}
}
}
problemDetails.Extensions.Add("Invalid Fields", codeMessages);
return BadRequest(problemDetails);
}
}
catch (Exception)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
那么有没有办法在集中的地方(例如中间件或其他东西)来处理这个问题。
预期回应:
{
"type": "Type",
"title": "Title",
"status": 400,
"detail": "Detail",
"instance": "Instance",
"Invalid Fields": [
{
"field": "Proprty 1",
"code": "01",
"message": "Invalid Proprty 1"
},
{
"field": "Property 2",
"code": "02",
"message": "Invalid Property 2"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我已经扩展ValidationAttribute
以实现所有属性的验证逻辑,下面是Property1
.
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
try
{
if (value != null)
{
propertyDisplayName = validationContext.DisplayName;
long property1 = (Int64)value;
Match match = Regex.Match($"{property1}", @"^\d+$", RegexOptions.IgnoreCase);
if (!string.IsNullOrWhiteSpace($"{property1}") && match.Success)
{
return ValidationResult.Success;
}
else
{
return new ValidationResult($"Invalid {propertyDisplayName}");
}
}
else
{
return new ValidationResult($"Invalid {propertyDisplayName}");
}
}
catch (Exception ex)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
如果有一种方法可以在扩展ValidationAttribute
类中处理这种情况,那也对我有用。
注意:目标框架是.Net5
我可以通过在ConfigureServices
Startup.cs 方法中使用以下代码来解决该问题。
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest).ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = c =>
{
ProblemDetails problemDetails = new ProblemDetails();
problemDetails.Status = StatusCodes.Status400BadRequest;
problemDetails.Title = "One or more validation errors occurred.";
problemDetails.Type = "https://tools.ietf.org/html/rfc7231#section-6.5.1";
List<FieldCodeMessage> codeMessages = new List<FieldCodeMessage>();
foreach (var modelState in c.ModelState)
{
if (modelState.Value.ValidationState == Microsoft.AspNetCore.Mvc.ModelBinding.ModelValidationState.Invalid)
{
string[] errorMessageCode = modelState.Value.Errors.Select(a => a.ErrorMessage).FirstOrDefault().Split(':');
string code = errorMessageCode[0];
string message = errorMessageCode[1];
codeMessages.Add(new FieldCodeMessage(field: modelState.Key, code: code, message: message));
}
}
problemDetails.Extensions.Add("Invalid Fields", codeMessages);
return new BadRequestObjectResult(problemDetails);
};
});
Run Code Online (Sandbox Code Playgroud)
我必须使用一种技巧,通过在扩展的方法:
中使用像这样的分隔符来传递错误代码和消息。IsValid
ValidationAttribute
return new ValidationResult("01:Proprty 1");
Run Code Online (Sandbox Code Playgroud)
如果大家有更好的方法或者建议,欢迎评论留言。我很高兴知道。
归档时间: |
|
查看次数: |
8111 次 |
最近记录: |