gpt4 book ai didi

c# - 以干净的方式在 Asp.Net Core API 中实现 ProblemDetails 的最佳方法

转载 作者:行者123 更新时间:2023-12-05 04:41:18 26 4
gpt4 key购买 nike

我需要使用 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)
{
...
}
}

那么有没有一种方法可以在像中间件或其他东西这样的集中位置处理这个问题。

预期响应:

{
"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"
}
]
}

我已经扩展了 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)
{
...
}
}

如果在扩展的 ValidationAttribute 类中也有处理这种情况的方法,那对我也适用。

注意:目标框架是.Net5

最佳答案

我可以通过在 Startup.cs 的 ConfigureServices 方法中使用以下代码来解决这个问题。

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

我不得不使用一种技巧,通过在扩展的 ValidationAttribute< 的 IsValid 方法中使用 : 定界符将错误代码与消息一起传递.

return new ValidationResult("01:Proprty 1");

如果大家有更好的做法或建议,欢迎留言。我很乐意知道。

关于c# - 以干净的方式在 Asp.Net Core API 中实现 ProblemDetails 的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70110306/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com