El tipo de acción de retorno en ASP.NET Core

Antes de Asp.net Core, todos los valores de retorno de Action eran ActionResult, y Json (), File () y otros métodos devolvían las subclases de ActionResult. Y después de que Core fusionó MVC con WebApi, el sistema de valor de retorno de Action también ha cambiado mucho.

Clase ActionResult

La clase ActionResult es el tipo de valor de retorno más utilizado. Básicamente, siga el conjunto anterior de cosas de Asp.net MVC, usarlo en la mayoría de los casos no es un problema. Por ejemplo, úselo para volver a ver, regresar a json, regresar a archivo, etc. Si es asíncrono, use Tarea

    public class TestController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult MyFile()
        {
            return File(new byte[] { }, "image/jpg");
        }

        public ActionResult MyJson()
        {
            return Json(new { name = "json" });
        }

        public ActionResult Ok()
        {
            return Ok();
        }
    }

Interfaz IActionResult

La clase ActionResult implementa la interfaz IActionResult, por lo que IActionResult se puede usar en lugar de ActionResult. Si también es asíncrono, use el paquete de tareas como valor de retorno.

   public class ITestController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult MyFile()
        {
            return File(new byte[] { }, "image/jpg");
        }

        public IActionResult MyJson()
        {
            return Json(new { name = "json" });
        }

        public IActionResult HttpOk()
        {
            return Ok();
        }

        public async Task<IActionResult> AsyncCall()
        {
            await Task.Delay(1000);

            return Content("ok");
        }
    }

Regresar directamente a POCO

La acción del controlador de Asp.net Core puede tomar el tipo POCO (en realidad no necesariamente es una clase POCO, puede ser de cualquier tipo, pero generalmente devuelve la clase POCO como viwemodel cuando se usa) como el valor de retorno, no necesariamente ActionResult o IActionResult. El framework Asp.net Core nos ayudará a serializar y regresar automáticamente al front end. Por defecto, se utiliza la serialización json. Si también es asíncrono, use el paquete de tareas como valor de retorno.

   public class Person
    {
        public string Name { get; set; }

        public string Sex { get; set; }
    }

    public class ITestController : Controller
    {

          public Person GetPerson()
        {
            return new Person { Name = "abc", Sex = "f" };
        }

        public async Task<List<Person>> GetPersons()
        {
            await Task.Delay(1000);

            return new List<Person> {
            new Person { Name = "abc", Sex = "f" },
            new Person { Name = "efg", Sex = "m" }
            };
        }
    }

ActionResult <T> clase genérica

Cuando diseñamos un sistema webapi tranquilo, estamos acostumbrados a usar POCO como valor de retorno. Por ejemplo, diseñamos una API para obtener Person. Obtenga la persona 001 a través de / person / 001 url.

    [Route("[controller]")]
    public class PersonController : Controller
    {
        IPersonRepository _repository;
        PersonController(IPersonRepository repository) 
        {
            _repository = repository;
        }

        [HttpGet("{id}")]
       public Person Get(string id)
        {
            return _repository.Get(id);
        }
    }

Este método parece no ser un problema, pero en realidad hay un pequeño problema. Si el método repository.Get no encuentra los datos basados ​​en la identificación, devolverá nulo. Si se utiliza nulo como valor de retorno de Action, el marco final se convertirá a 204 código de estado http.

204 significa Sin contenido. Como api relajante, la semántica de 204 será problemática aquí. El código de estado más adecuado aquí es 404 NO ENCONTRADO. Entonces vamos a cambiarlo:

        [HttpGet("{id}")]
       public Person Get(string id)
        {
            var person = _repository.Get(id);
            if (person == null)
            {
                Response.StatusCode = 404;
            }

            return person;
        }

Ahora, si no se pueden encontrar los datos de la persona, el sistema devolverá 404 No encontrado.

Pero esto obviamente no es lo suficientemente elegante, porque ControllerBase tiene un método incorporado NotFoundResult NotFound (). El código se ve más y más claro usando este método. Continuar cambiando:

        [HttpGet("{id}")]
       public Person Get(string id)
        {
            var person = _repository.Get(id);
            if (person == null)
            {
                return NotFound();
            }
            return person;
        }

Desafortunadamente, este código VS provocará un error. Porque el tipo de valor de retorno es inconsistente. El valor de retorno de la firma del método es Person, pero NotFoundResult se devolverá dentro del método y Person se devolverá una vez.

Para resolver este problema, es hora de que aparezca ActionResult <T>. Seguimos cambiando:

        [HttpGet("{id}")]
       public ActionResult<Person> Get(string id)
        {
            var person = _repository.Get(id);
            if (person == null)
            {
                return NotFound();
            }

            return person;
        }

Ahora VS no informará un error, puede funcionar normalmente después de ejecutarlo. Pero también es muy extraño pensar en ello. ¿Por qué el tipo de valor de retorno se cambia a ActionResult <Person> y no está mal? ¿Obviamente el tipo de valor de retorno no es consistente con la firma del método?

ActionResult en profundidad <T>

Siguiendo la pregunta anterior, echemos un vistazo al interior de ActionResult:

vea aquí para comprender que hay dos métodos de operador implícitos integrados en el ActionResult original <T>. El operador implícito se utiliza para declarar la conversión de tipo implícito.

public static implicit operator ActionResult<TValue>(ActionResult result); 

Indica que el tipo ActionResult se puede convertir al tipo ActionResult <TValue>.

public static implicit operator ActionResult<TValue>(TValue value)

Indica que el tipo TValue se puede convertir al tipo ActionResult <TValue>.

Debido a estos dos métodos, se realiza una conversión de tipo automática cuando el tipo ActionResult o TValue se asigna a ActionResult <T>. Entonces VS no informará un error aquí.

Resumen

  1. La mayoría de las veces el valor de retorno de Action puede usar ActionResult / IActionResult
  2. Al diseñar API relajantes, puede usar directamente la clase POCO como valor de retorno
  3. Si desea diseñar una acción que admita el valor de retorno de la clase POCO o la clase ActionResult como valor de retorno, puede usar ActionResult <T> como valor de retorno
  4. La razón por la que ActionResult <T> puede admitir dos tipos de tipos de valor de retorno es porque el operador implícito tiene 2 métodos de conversión implícitos incorporados

Supongo que te gusta

Origin www.cnblogs.com/kklldog/p/aspnetcore-actionresult.html
Recomendado
Clasificación