Я пытаюсь вернуть согласованный ответ с аналогичной структурой, возвращаемой для всех запросов.
Объект, который я хочу вернуть, будет инкапсулирован в элемент Result.
Я хотел имеют одинаковую структуру во время:
- результат успеха
- проверка модели
- исключение
Я создал 3 отдельных middleware
для этой цели.
Но в моем случае middleware
для обёртывания responses
обернул результат из exceptionc filter
, а также ответы из ValidationFilter
.
Вывод, который я получил во время исключения:
{
"Result": {
"Result": null,
"StatusCode": 0,
"Message": "Identification id Invalid!",
"Errors": null
},
"StatusCode": 500,
"Message": null,
"Errors": null
}
Вывод во время исключения должен выглядеть следующим образом:
{
"Result": null,
"StatusCode": 0,
"Message": "Identification id Invalid!",
"Errors": null
}
Аналогично, у меня та же проблема для модели ошибка валидации:
{
"Result": {
"Result": null,
"StatusCode": 200,
"Message": "{\"Errors\":[{\"FieldName\":\"State\",\"Message\":\"'State' must not be empty.\"}]}",
"Errors": "Invalid Request"
},
"StatusCode": 200,
"Message": null,
"Errors": null
}
Класс Wrapper
public class ValidationFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
if (!context.ModelState.IsValid)
{
var errorsInModelState = context.ModelState
.Where(x => x.Value.Errors.Count > 0)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors.Select(x => x.ErrorMessage)).ToArray();
var errorResponse = new ErrorResponse();
foreach (var error in errorsInModelState)
{
foreach (var subError in error.Value)
{
var errorModel = new ErrorModel
{
FieldName = error.Key,
Message = subError
};
errorResponse.Errors.Add(errorModel);
}
}
var responseModel = new ApiResponseModel("Invalid Request", JsonConvert.SerializeObject(errorResponse), (int)HttpStatusCode.OK);
context.Result = new ObjectResult(responseModel);
return;
}
await next();
// after controller
}
}
ApiExceptionFilter
public class ApiExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
ApiResponseModel responseModel = null;
if (context.Exception is ApiException)
{
// handle explicit 'known' API errors
var ex = context.Exception as ApiException;
context.Exception = null;
responseModel = new ApiResponseModel(ex.Message);
context.HttpContext.Response.StatusCode = ex.StatusCode;
}
else
{
var msg = "An unhandled error occurred.";
string stack = null;
responseModel = new ApiResponseModel(msg);
context.HttpContext.Response.StatusCode = 500;
// handle logging here
}
// always return a JSON result
context.Result = new JsonResult(responseModel);
base.OnException(context);
}
}
Как можно объединить все фильтры в одном коде и обработать все ответы из одного фильтра, сохранив согласованность во всех ответах?