ASP .NET Core  -  Passando parâmetros para Actions - I


Neste artigo vamos recordar como é feita a passagem de parâmetros para Actions dos controladores na ASP .NET Core no ambiente do ,NET 5.0.

Passar parâmetros para Actions é uma parte essencial da construção de aplicações Web API RESTful e como veremos existem muitas formas de passar parâmetros para os métodos de uma API ou seja os endpoints.

Vamos recordar como fazer isso usando a ASP.NET Core com o .NET Core SDK 5 e o Visual Studio 2019 Community na versão 16.8.4.

Os controladores de ASP.NET Core usam o middleware de roteamento para corresponder as URLs de requisições de entrada e mapeá-las para Actions. Os Modelos de rota :

As Actions podem ser roteadas por convenção ou por atributo. Colocar uma rota no controlador ou na Action a torna roteada por atributo, e, as  APIs REST geralmente usam o roteamento por atributos.

Para isso vamos criar um projeto ASP.NET Core Web Application chamado AspnParametros usando o template ASP .NET Core Web API marcando a opção Enable OpenAPI support :

Vamos usar o controlador padrão criado e criar alguns métodos Actions ao longo do artigo.

Note que neste projeto não temos definida nenhuma rota convencional :

app.UseEndpoints(endpoints =>
 {
      endpoints.MapControllers();
 });

E que temos apenas um método Action HttpGet definido no controlador.

No controlador esta sendo usado o atributo [Route] que define uma rota padrão para acessar os métodos Actions:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    ....
}

Aqui o atributo [Route("[controller]")] define que para acessar qualquer endpoint devemos usar na url : localhost:XXX/weatherforecast

Passando parâmetros como parte de uma URL

Ao passar parâmetros em uma URL precisamos definir uma rota que contém o parâmetro.

Vamos então definir o seguinte método Action no controlador WeatherForecastController :

        [Route("{dias}")]
        [HttpGet]
        public IActionResult Get(int dias)

        {
            var rng = new Random();
            return new JsonResult(new WeatherForecast
            {
                Date = DateTime.Now.AddDays(dias),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            });
        }

Observe que criamos o método HttpGet que vai retornar a previsão do tempo para um dia que esta definido pelo parâmetro dias do tipo int que representa para quantos dias de antecedência queremos a previsão do tempo.

Aqui o parâmetro dias faz parte do roteamento definindo pelo atributo [Route("{dias}"] na Action. Dessa forma uma URL válida para acessar este endpoint seria o seguinte:

localhost://5001/weatherforecast/2

Podemos também usar o atributo [FromRoute] antes do tipo da variável no método Action que vai funcionar da mesma forma:

        [HttpGet("{dias}")]
        public IActionResult Get(
[FromRoute] int dias)

        {
            var rng = new Random();
            return new JsonResult(new WeatherForecast
            {
                Date = DateTime.Now.AddDays(dias),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            });
        }

Aqui podemos ver que estamos fornecendo um argumento template "{id}". Isso fará com que a rota HTTP Get se pareça com "weatherforecast/1" - onde o id é uma variável.

Passando parâmetros em uma querystring

Este é um método muito comum para passar parâmetros adicionais, porque não exige que alteremos o roteamento, portanto, também é compatível com versões anteriores.

Vamos alterar o método GET para permitir que as temperaturas sejam ordenadas usando um parâmetro ordenarTemperadura que será passado via querystring:

        [HttpGet]
        public IEnumerable<WeatherForecast> Get([FromQuery] bool ordenarTemperatura = false)
        {
            var rng = new Random();
            var forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            });

            if (ordenarTemperatura)
            {
                forecasts = forecasts.OrderByDescending(f => f.TemperatureC);
            }

            return forecasts;
        }

Inicialmente o parâmetro ordenarTemperatura tem o valor padrão igual a false e assim as temperaturas não estarão ordenadas.

Note que usamos o atributo [FromQuery] para indicar que o parâmetro será obtido a partir da query string. Assim para passar o parâmetro com valor igual a true podemos fazer assim:

https://localhost:5001/weatherforecast?ordenarTemperadura=true

No exemplo estamos usando apenas um parâmetro mas podemos usar vários :

GET: weatherForecast?key1=value1&key2=value2&key3=value3

Lembrando que a URL necessita se decodificada de forma adequada para trabalhar corretamente.

Passando um objeto em uma querystring

Além de parâmetros podemos também passar um objeto complexo em uma querystring.

Vamos supor que para o nosso exemplo desejamos filtrar por cidade e definir a ordenação por temperatura.

Neste caso vamos criar uma classe chamada WeatherForecastFiltros que será o nosso objeto complexo e nesta classe vamos criar duas propriedades que iremos usar para passar os valores dos parâmetros:

      public class WeatherForecastFiltros
    {
        public bool OrdenarTemperatura { get; set; }
        public string Cidade { get; set; }
    }

Precisamos agora ajustar a classe WeatherForecast incluindo a propriedade City e incluir também o array Cities no controlador com os nomes de algumas cidades :

private static readonly string[] Cities = new[]
{
      "Campinas", "São Paulo", "Curitiba", "Salvador", "Brasília", "Rio de Janeiro"
};

A seguir podemos alterar o método anterior conforme abaixo agora passando via o tipo complexo WeatherForecastFiltros e os valores para Cidade e OrdernarTemperatura na querystring:

        [HttpGet["GetFiltrado"]]
        public IEnumerable<WeatherForecast> GetFiltrado([FromQuery]
WeatherForecastFiltros filtros)
        {
            var rng = new Random();
            var forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]

                City = filtros.Cidade             

            });

            if (filtros.OrdenarTemperatura)
            {
                forecasts = forecasts.OrderByDescending(f => f.TemperatureC);
            }

            return forecasts;
        }

Observe que definimos um nome especifico - GetFiltrado -  para acessar este endpoint.

Para exibir as temperaturas ordenadas para a cidade de Salvador podemos definir a seguinte chamada:

https://localhost:5001/weatherforecast/GetFiltrado?OrdenarTemperatura=true&Cidade=Salvador

Note que temos mais de um parâmetro em uma querystring usamos o caractere & para indicar a separação entre os parâmetros.

Portanto, os parâmetros podem ser passados por seus nomes, mesmo se estiverem dentro de uma classe. Além disso, eles são acessíveis apenas por seus nomes, sem qualquer prefixo de classe e isso significa que todas as propriedades devem ter nomes exclusivos.

Na próxima parte do artigo veremos vamos continuar com o assunto.

Pegue o projeto aqui:   AspnParametros.zip

"Paulo, apóstolo enviado, não da parte de homens nem por meio de pessoa alguma, mas por Jesus Cristo e por Deus Pai, que o ressuscitou dos mortos,"
Gálatas 1:1

Referências:


José Carlos Macoratti