Fluent 验证自定义响应 ASP.NET Core Web API
Fluent validation custom response ASP.NET Core Web API
我正在研究 ASP.NET Core 6 Web API 项目。我们使用 Fluent Validation。我如何 return 自定义响应。请指教
我想针对页面、限制、日期等不同的验证错误发送自定义响应
这是我默认得到的响应:
{
"type": "",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-097c689850af328c49705cea77fc6fbd-0c7defe165d9693f-00",
"errors": {
"Page": [
"Page value should be greater than 0"
],
"Limit": [
"Limit value should be greater than 0"
]
}
}
这是我想要得到的回复:
{
"traceId": "e45b3398-a2a5-43eb-8851-e45de1184021",
"timestamp": "2021-06-28T00:32:06.548Z",
"errors": [
{
"errorCode": "Contract Violation",
"message": "Page should be greater than 0",
"priority": "MEDIUM",
"properties": {
"name": "string",
"value": "string"
}
}
]
}
这是我的代码:
public async Task<IActionResult> Get([FromQuery] DataParameter input)
{
}
public class DataParameter
{
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public int Page { get; set; }
public int Limit { get; set; }
}
public class QueryParameterValidator : AbstractValidator<QueryParameter>
{
public QueryParameterValidator()
{
RuleFor(model => model.Page)
.GreaterThan(0)
.WithMessage("Page value should be greater than 0");
RuleFor(model => model.Limit)
.GreaterThan(0)
.WithMessage("Limit value should be greater than 0");
RuleFor(model => model.StartDate)
.Matches(@"^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$")
.WithMessage("Transaction from date should be in the pattern of YYYY-MM-DD");
RuleFor(model => model.EndDate)
.Matches(@"^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$")
.WithMessage("Transaction to date should be in the pattern of YYYY-MM-DD");
}
}
这是您可以遵循的完整工作演示:
型号:
public class ErrorDetail
{
public string traceId { get; set; }
public DateTime timestamp { get; set; }
public List<Error> errors { get; set; } = new List<Error>();
}
public class Error
{
public string errorCode { get; set; }
public string message { get; set; }
public string priority { get; set; }
public Properties properties { get; set; }=new Properties();
}
public class Properties
{
public string name { get; set; }
public string value { get; set; }
}
静态class:
public static class CustomProblemDetails
{
public static ErrorDetail ErrorDetail { get; set; } =new ErrorDetail();
public static IActionResult MakeValidationResponse(ActionContext context)
{
var problemDetails = new ValidationProblemDetails(context.ModelState)
{
Status = StatusCodes.Status400BadRequest,
};
foreach (var keyModelStatePair in context.ModelState)
{
var errors = keyModelStatePair.Value.Errors;
if (errors != null && errors.Count > 0)
{
if (errors.Count == 1)
{
var errorMessage = GetErrorMessage(errors[0]);
ErrorDetail.errors.Add(new Error()
{
errorCode= "Contract Violation",
message = errorMessage,
priority= "MEDIUM",
properties= new Properties() {
name = "string",
value = "string"
}
});
}
else
{
var errorMessages = new string[errors.Count];
for (var i = 0; i < errors.Count; i++)
{
errorMessages[i] = GetErrorMessage(errors[i]);
ErrorDetail.errors.Add(new Error()
{
errorCode = "Contract Violation",
message = errorMessages[i],
priority = "MEDIUM"
});
}
}
}
}
ErrorDetail.traceId = context.HttpContext.TraceIdentifier;
ErrorDetail.timestamp = DateTime.Now;
var result = new BadRequestObjectResult(ErrorDetail);
result.ContentTypes.Add("application/problem+json");
return result;
}
static string GetErrorMessage(ModelError error)
{
return string.IsNullOrEmpty(error.ErrorMessage) ?
"The input was not valid." :
error.ErrorMessage;
}
}
注册:
builder.Services.AddControllers().AddFluentValidation().ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = CustomProblemDetails.MakeValidationResponse;
});
结果:
我正在研究 ASP.NET Core 6 Web API 项目。我们使用 Fluent Validation。我如何 return 自定义响应。请指教
我想针对页面、限制、日期等不同的验证错误发送自定义响应
这是我默认得到的响应:
{
"type": "",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-097c689850af328c49705cea77fc6fbd-0c7defe165d9693f-00",
"errors": {
"Page": [
"Page value should be greater than 0"
],
"Limit": [
"Limit value should be greater than 0"
]
}
}
这是我想要得到的回复:
{
"traceId": "e45b3398-a2a5-43eb-8851-e45de1184021",
"timestamp": "2021-06-28T00:32:06.548Z",
"errors": [
{
"errorCode": "Contract Violation",
"message": "Page should be greater than 0",
"priority": "MEDIUM",
"properties": {
"name": "string",
"value": "string"
}
}
]
}
这是我的代码:
public async Task<IActionResult> Get([FromQuery] DataParameter input)
{
}
public class DataParameter
{
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public int Page { get; set; }
public int Limit { get; set; }
}
public class QueryParameterValidator : AbstractValidator<QueryParameter>
{
public QueryParameterValidator()
{
RuleFor(model => model.Page)
.GreaterThan(0)
.WithMessage("Page value should be greater than 0");
RuleFor(model => model.Limit)
.GreaterThan(0)
.WithMessage("Limit value should be greater than 0");
RuleFor(model => model.StartDate)
.Matches(@"^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$")
.WithMessage("Transaction from date should be in the pattern of YYYY-MM-DD");
RuleFor(model => model.EndDate)
.Matches(@"^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$")
.WithMessage("Transaction to date should be in the pattern of YYYY-MM-DD");
}
}
这是您可以遵循的完整工作演示:
型号:
public class ErrorDetail
{
public string traceId { get; set; }
public DateTime timestamp { get; set; }
public List<Error> errors { get; set; } = new List<Error>();
}
public class Error
{
public string errorCode { get; set; }
public string message { get; set; }
public string priority { get; set; }
public Properties properties { get; set; }=new Properties();
}
public class Properties
{
public string name { get; set; }
public string value { get; set; }
}
静态class:
public static class CustomProblemDetails
{
public static ErrorDetail ErrorDetail { get; set; } =new ErrorDetail();
public static IActionResult MakeValidationResponse(ActionContext context)
{
var problemDetails = new ValidationProblemDetails(context.ModelState)
{
Status = StatusCodes.Status400BadRequest,
};
foreach (var keyModelStatePair in context.ModelState)
{
var errors = keyModelStatePair.Value.Errors;
if (errors != null && errors.Count > 0)
{
if (errors.Count == 1)
{
var errorMessage = GetErrorMessage(errors[0]);
ErrorDetail.errors.Add(new Error()
{
errorCode= "Contract Violation",
message = errorMessage,
priority= "MEDIUM",
properties= new Properties() {
name = "string",
value = "string"
}
});
}
else
{
var errorMessages = new string[errors.Count];
for (var i = 0; i < errors.Count; i++)
{
errorMessages[i] = GetErrorMessage(errors[i]);
ErrorDetail.errors.Add(new Error()
{
errorCode = "Contract Violation",
message = errorMessages[i],
priority = "MEDIUM"
});
}
}
}
}
ErrorDetail.traceId = context.HttpContext.TraceIdentifier;
ErrorDetail.timestamp = DateTime.Now;
var result = new BadRequestObjectResult(ErrorDetail);
result.ContentTypes.Add("application/problem+json");
return result;
}
static string GetErrorMessage(ModelError error)
{
return string.IsNullOrEmpty(error.ErrorMessage) ?
"The input was not valid." :
error.ErrorMessage;
}
}
注册:
builder.Services.AddControllers().AddFluentValidation().ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = CustomProblemDetails.MakeValidationResponse;
});
结果: