我有一个非常简单的控制器操作,它接受一个视图模型。我只想检查代码中的模型,如果它无效,则将模型状态转储为BadRequest。
[HttpPost]
[Route("SaveBraceStep1")]
[SwaggerOperation(OperationId = "SaveBraceStep1")]
[ProducesResponseType(200, Type = typeof(VM.ProjectBraceDataModelStep1))]
public async Task<IActionResult> SaveBraceStep1(VM.ProjectBraceDataModelStep1 model)
{
if (!ModelState.IsValid)
{
return new BadRequestObjectResult(ModelState.Errors());
}
var project = await bracingDataService.SaveBraceStep1(model);
return Ok(project);
}当结果返回到Chrome时,它与预期的一样。

我有一个http拦截器,如下所示:
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
export class HttpErrorInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(catchError(err => {
// how can I read the results of the ModelState here
console.log(err);
return throwError('An error has been thrown');
}));
}
}下面是转储到控制台的内容

我已经搜索了大量的google搜索和用户blobs,但我似乎找不到一种公认的简洁的方法来做到这一点。
我真的被打动了,因为我希望到现在为止这已经相当标准化了。
有什么想法吗?提前谢谢你。祝你编码愉快!
~Mike
发布于 2020-10-17 04:04:46
好的,我在https://www.strathweb.com/2018/07/centralized-exception-handling-and-request-validation-in-asp-net-core/的帮助下弄明白了这一点
您基本上必须注册一个新的Action Type,然后将其插入到管道中。
public Task ExecuteResultAsync(ActionContext context)
{
var modelStateEntries = context.ModelState.Where(e => e.Value.Errors.Count > 0).ToArray();
var errors = new List<ValidationError>();
var details = "See ValidationErrors for details";
if (modelStateEntries.Any())
{
if (modelStateEntries.Length == 1 && modelStateEntries[0].Value.Errors.Count == 1 && modelStateEntries[0].Key == string.Empty)
{
details = modelStateEntries[0].Value.Errors[0].ErrorMessage;
}
else
{
foreach (var modelStateEntry in modelStateEntries)
{
foreach (var modelStateError in modelStateEntry.Value.Errors)
{
var error = new ValidationError
{
Name = modelStateEntry.Key,
Description = modelStateError.ErrorMessage
};
errors.Add(error);
}
}
}
}
var problemDetails = new ValidationProblemDetails
{
Status = 400,
Title = "Request Validation Error",
Instance = $"urn:myorganization:badrequest:{Guid.NewGuid()}",
Detail = details,
ValidationErrors = errors
};
context.HttpContext.Response.StatusCode = 400;
var json = JsonConvert.SerializeObject(problemDetails);
context.HttpContext.Response.WriteAsync(json);
return Task.CompletedTask;
}
}
public class ValidationProblemDetails : ProblemDetails
{
public ICollection<ValidationError> ValidationErrors { get; set; }
}
public class ValidationError
{
public string Name { get; set; }
public string Description { get; set; }
}然后在startup.cs中注册它。
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = ctx => new ValidationProblemDetailsResult();
});然后连上拦截器
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(private uiService: Services.UIService, private injector: Injector) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(catchError((err: HttpErrorResponse) => {
const reader = new FileReader();
reader.addEventListener('loadend', (e) => {
const result = this.buildResponse(JSON.parse(e.srcElement['result']));
this.uiService.HttpError(result);
});
reader.readAsText(err.error);
return throwError(err);
}));
}
buildResponse(e: any): ApplicationHttpErrorResponse {
const model: ApplicationHttpErrorResponse = { ValidationErrors: [] };
if (e.ValidationErrors && e.ValidationErrors.length > 0) {
for (let i = 0; i < e.ValidationErrors.length; i++) {
const validator: ApplicationHttpError = {
Name: e.ValidationErrors[i].Name,
Description: e.ValidationErrors[i].Description
};
model.ValidationErrors.push(validator);
}
}
return model;
}
}然后可以在UI服务中使用它来向最终用户显示问题。
https://stackoverflow.com/questions/64393905
复制相似问题