Как создать метод контроллера, который может возвращать разные коды возврата ошибок в ASP.NET ядро 3.1

#asp.net-core

#asp.net-core

Вопрос:

Мне нужно возвращать разные коды httpstatus на основе моего возвращаемого объекта (результата). Если это ошибка, свойство Error содержит сериализованную информацию, состоящую из кода ошибки и сообщения, предоставленного моей службой. У меня есть метод контроллера ниже:

 [HttpPost]
    public ActionResult<BasicItemDTO> CreateValue(BasicIItemCreationDTO value)
    {
        Result<BasicItemDTO> res = ValuesService.CreateValue(value);
        if (res.IsFailure) return ErrorFromResult(res.Error);
        ActionResult<BasicItemDTO> response = CreatedAtRoute("GetValue", res.Value);
        return  response;
    }
  

и ErrorFromResult определяется как

 protected IActionResult ErrorFromResult(string ErrorMessage)
    {
        ErrorCode = GetCode(ErrorMessage)
    ErrorDetail = GetMessage(Message);
    switch (ErrorCode)
            {
                case "BadReqest":
                    return BadRequest(ErrorDetail);
                case "Conflict":
                    ProblemDetails PD= GenerateResponse(ErrorDetail);
                    return Conflict(PD);
                case "NotFound":
                    return NotFound(ErrorDetail);
            }
}
  

Я борюсь с тем, какой тип возврата в ErrorFromResult. Каким должен быть возвращаемый тип ErrorFromResult?

Комментарии:

1. Возврат IActionResult выдает вам какую-либо ошибку?

Ответ №1:

Поскольку это API, измените возвращаемый тип CreateValue на IActionResult и завершите ответ кодом состояния или Json подобным этому:

 [HttpPost]
public IActionResult CreateValue(BasicIItemCreationDTO value)
{
  Result<BasicItemDTO> res = ValuesService.CreateValue(value);
  if (res.IsFailure) return ErrorFromResult(res.Error);
  //ActionResult<BasicItemDTO> response = CreatedAtRoute("GetValue", res.Value);
  var url = Url.RouteUrl("route_name", route_values)
  return Created(url, the created value);
}
  

Ответ №2:

Вам нужно добавить метку defualt в инструкции switch. Метка по умолчанию будет выполнена, если вышеуказанные случаи не выполняются.

 switch (ErrorCode)
{
    case "Conflict":
        ProblemDetails PD = GenerateResponse(ErrorDetail);
        return Conflict(PD);
    case "NotFound":
        return NotFound(ErrorDetail);
    default:
        return BadRequest(ErrorDetail);
}
  

Кроме того, как сказал @HMZ, вы можете изменить возвращаемый тип CreateValue на IActionResult , сделать его таким же, как возвращаемый тип ErrorFromResult .

Ответ №3:

Хорошо, я понял это. Если я использую IActionResult для метода CreateValue, часть errorFromResult работает нормально, но счастливый путь не компилируется, поскольку возвращаемый тип CreatedAtRoute не преобразуется в IActionResult. Вам нужно использовать реализацию CreateAtRoute с 3 параметрами. Приведенный ниже код компилируется и выполняется, как и ожидалось.

  [HttpPost]
    public IActionResult CreateValue(BasicIItemCreationDTO value)
    {
        Result<BasicItemDTO> res = ValuesService.CreateValue(value);
        if (res.IsFailure) return ErrorFromResult(res.Error);
        IActionResult response = CreatedAtRoute("GetValue",new {ValueId= res.Value.Id },res.Value);
        return  response;
    }
  

Спасибо за совет по умолчанию для switch. Я опустил это для краткости, поскольку это не имело прямого отношения к вопросу.