Общий тип возврата ActionResult для API-контроллера - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть следующий вариант использования для метода GetProducts().

Хороший путь: Возвращает массив типа product: Product[]

Неверный путь: Возвращает код состояния 500 и описательныйстроковое сообщение об ошибке.

(<?Type?> ниже - моя собственная разметка для целей этого поста)

[Route("api/[controller]/[action]")]
[ApiController]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public ActionResult<?Type?> GetProducts()
    {
        try
        {
            Product[] products = DataAccess.GetProductsFromDb();
            return products;
        }
        catch 
        {
            Response.StatusCode = 400;
            return "Error retrieving products list"
        }
    }
}

Есть ли способ объявить результат действия универсального типа иливозможно, два типа, чтобы это могло работать?

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Вы можете вернуть ActionResult<Product[]> как пожелаете.Однако для сценария ошибки вы можете использовать вспомогательный метод StatusCode() для возврата сообщения об ошибке, как показано ниже:

[Route("api/[controller]/[action]")]
[ApiController]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public ActionResult<Product[]> GetProducts()
    {
        try
        {
            Product[] products = DataAccess.GetProductsFromDb();
            return products;
        }
        catch 
        {
            return StatusCode(500, "Error retrieving products list");
        }
    }
}
0 голосов
/ 04 декабря 2018

Вы бы вернули IActionResult.Я настоятельно рекомендую сделать это асинхронно.Вот как вы можете вернуть что-нибудь через метод контроллера:

[Route("api/{controller}")]
public class ProductsController : Controller
{
    [HttpGet]
    public async Task<IActionResult> GetProducts()
    {
        var products = DataAccess.GetProductsFromDb();
        if (products is null)
        {
            return Ok(products);
        }
        else
        {
            return NotFound("Item not found!");
        }
    }
}

Обратите внимание, что Ok и NotFound являются методами в абстрактном классе Controller, который позволяет вам возвращать любой объект, который вы хотите, или нетобъект вообще.

Я настоятельно рекомендую, прежде чем продолжать использовать ядро ​​.net, взгляните на пример шаблона проекта в Visual Studio или, если вы разрабатываете в другой среде IDE, запустите dotnet new mvc в своем терминале.

Если вы хотите обработать исключение, вы должны обработать его на самом низком уровне.Предполагая, что GetProductsFromDb () является самым низким уровнем, и у вас нет сервисного уровня (вы будете сожалеть об этом выборе дизайна в производстве!), Вы бы попробовали / поймали.

[Route("api/{controller}")]
public class ProductsController : Controller
{
    [HttpGet]
    public async Task<IActionResult> GetProducts()
    {
        Products[] products;
        try
        {
            products = DataAccess.GetProductsFromDb();
        }
        catch(Exception e)
        {
            Log.Error(e, "Unable to receive products");
            return InternalServerError("Unable to retrieve products, please try again later");
        }
        if (products is null)
        {
            return BadRequest("Error retrieving products list");
        }
        else
        {
            return Ok(products);
        }
    }
}

Скорость НЕ важнее стабильностив большинстве случаев, и, конечно, не на этой стадии развития.стоимость получения исключения незначительна для чего-то такого высокого уровня.

...