ASP .NET MVC - Exibindo uma lista de itens selecionáveis - Dropdownlist


Se você pretende desenvolver páginas web dinâmicas usando a tecnologia ASP .NET MVC provavelmente vai se deparar com a tarefa de ter que exibir uma lista de itens selecionáveis em uma página.

Uma lista de itens selecionáveis é obtida usando o controle DropDownList que na verdade é renderizado como um elemento Select da HTML que usa a tag <select></select>.

É uma tarefa simples mas se você procurar na web sobre o assunto pode ficar um pouco confuso com as informações obtidas se estiver começando agora com a tecnologia ASP .NET MVC ou se você for usuário dos Web Forms da ASP .NET.

Uma das causas da confusão é que esta tarefa pode ser feito de diversas formas e isso pode variar dependendo do tipo de projeto (Usando JQuery, Json, etc.), do tipo engine usado no projeto ( .ASPX ou Razor), da origem dos itens (arquivo XML, arquivo Texto, Banco de dados, lista de itens, etc.) e qual a linguagem usada (C# ou VB .NET)

Este artigo procura ser bem direto e objetivo mostrando apenas o que é necessário para trabalhar com o controle DropDownList na tecnologia ASP .NET MVC.

Então a primeira providência que devemos tomar é deixar bem claro o tipo de projeto adotado, qual o engine estamos usando e qual a origem dos itens a serem exibidos no controle DropDownList.

Para não tornar o artigo muito extenso eu vou começar mostrando como exibir uma lista de itens estáticos e depois uma forma mais simples de usar o controle DropDownlist com ASP .NET MVC; para isso eu vou usar em uma página web um controle DropDownList que exibirá o nome de algumas cidades brasileiras.

Neste cenário vamos usar:

Criando o projeto ASP .NET MVC

Abra o Visual Studio Express 2012 for Web e no menu File clique em New Project;

Selecione o template Visual Basic -> Web -> ASP .NET MVC 3 Web Application;

Informe o nome PreenchendoDropDownList e clique no botão OK;

Na próxima janela selecione o template Internet Application , o view Engine ASPX e clique no botão OK;

Será criado o projeto completo com a estrutura das pastas padrão de um projeto ASP .NET MVC.

Podemos observar no projeto asa seguintes pastas :

Não precisa ser muito esperto para perceber que estes diretórios contém os arquivos que irão implementar o MVC - Model , View e o Controller. (Modelo, Visão e Controlador)

Observe também que a aplicação utiliza uma master page chamada Site.master na pasta \Shared.

Vamos usar os arquivos e a estrutura que já foram criados por padrão de forma a minimizar o nosso trabalho.

Exibindo uma lista de itens estáticos

Exibir uma lista de itens estáticos é a forma mais simples de usar um DropDowList basta simplesmente incluir na view o código desejado. No nosso exemplo vamos exibir uma lista selecionável de anos, para isso abra o arquivo Index.aspx na pasta Views/Home e inclua neste arquivo o código abaixo:

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of IEnumerable (Of PreenchendoDropDownlist.Contato))" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   Preenchendo um dropdownlist com itens estáticos
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
   
  
 <select name="ano">
        <option>2010</option>
        <option>2011</option>
        <option>2012</option>
        <option>2013</option>
        <option>2014</option>
        <option>2015</option>
    </select>


</asp:Content>

Executando o projeto iremos obter o seguinte resultado:

Bem, se você quiser deixar a sua lista um pouco mais dinâmica podemos usar a classe DateTime e exibir o ano incrementando cada ano desejado. O código ficaria assim:

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   Preenchendo um dropdownlist com itens estáticos
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
   
    <select name="ano">
        <option><%= DateTime.Now.Year%></option>
        <option><%= DateTime.Now.AddYears(1).Year%></option>
        <option><%= DateTime.Now.AddYears(2).Year%></option>
        <option><%= DateTime.Now.AddYears(3).Year%></option>
        <option><%= DateTime.Now.AddYears(4).Year%></option>
        <option><%= DateTime.Now.AddYears(5).Year%></option>
    </select>


</asp:Content>

Uma outra forma de obter o mesmo resultado acima seria otimizar o nosso código conforme abaixo:


<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   Preenchendo um dropdownlist com itens estáticos
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
   
    <select name="ano">
         <% For i = 0 To 5 %>
            <option><%=
DateTime.Now.AddYears(i).Year%></option>
         <% Next%>
    </select>


</asp:Content>

O código usado lembra muito a ASP não é mesmo ???

Executando o projeto iremos obter o seguinte resultado:

Até agora o que estamos fazendo é apenas definir o código da nossa View.

E se quisermos definir um Model e um controler em um cenário mais complexo ?

Vamos então partir para a definição do Model na pasta Models e do controller na pasta Controllers e redefinição da nossa view na pasta Views.

Definindo o Model o Controller e o View

1 - Definindo a classe CidadeModel - o Model

Um modelo MVC contém toda a lógica da sua aplicação que não esta contida no Controlador ou na Visão, e deverá conter toda a sua lógica de negócio, validação e lógica de acesso a dados.

Vamos iniciar definindo o nosso modelo de dados. Como eu vou exibir os nomes de algumas cidade brasileiras vou criar uma classe na pasta Models chamada CidadeModel;

Clique com o botão direito do mouse sobre a pasta Models e selecione Add->Class;

A seguir informe o nome CidadeModel e defina o código desta classe conforme abaixo:

Public Class CidadeModel

    Public Property CidadeNome() As String

End Class

Esta classe define apenas a propriedade CidadeNome do tipo String.

2- Definindo a lista de cidades - o Controller

Um controlador é responsável por controlar a maneira como um usuário interage com uma aplicação MVC e possui o fluxo de controle lógico para uma aplicação ASP .NET MVC. É o controlador que determina que resposta será enviada de volta ao usuário quando ele faz uma requisição via navegador.

Agora vamos usar o controller HomeController.vb já criado por padrão na pasta Controllers e vamos definir uma lista de cidades.

Abra o arquivo HomeController.vb e defina dois métodos Index() na classes HomeController conforme abaixo:

Imports PreenchendoDropDownlist.CadastroEntities

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    <HttpGet> _
    Public Function Index() As ActionResult
        'Cria uma lista de itens selecionaveis que precisa ser vinculada a um dropdownlist
        Dim cidadeLista As New List(Of SelectListItem)()

        'Adiciona cidades a lista de cidades
        cidadeLista.Add(New SelectListItem() With { _
            .Text = "Brasília", _
            .Value = "Brasilia" _
        })

        cidadeLista.Add(New SelectListItem() With { _
            .Text = "Rio de Janeiro", _
            .Value = "Rio de Janeiro" _
        })

        cidadeLista.Add(New SelectListItem() With { _
            .Text = "São Paulo", _
            .Value = "São Paulo" _
        })

        cidadeLista.Add(New SelectListItem() With { _
            .Text = "Rio Grando do Sul", _
            .Value = "Rio Grande do Sul" _
        })

        cidadeLista.Add(New SelectListItem() With { _
            .Text = "Belo Horizonte", _
            .Value = "Belo Horizonte" _
        })

        'adiciona a lista de cidades ao objeto ViewBag
        ViewBag.cidadeLista = cidadeLista
        Return View()
    End Function


    <HttpPost> _
    Public Function Index(model As CidadeModel) As String
        'retorna o nome da cidade que for selecionado no dropdownlist
        Return model.CidadeNome
    End Function

    Function About() As ActionResult
        Return View()
    End Function
End Class

Este código define dois métodos Index():

  1. Public Function Index() As ActionResult - HttpGet - Que expõe a lista de cidades para a view;

Este método possui utiliza 3 propriedades:

  1. Public Function Index(model As CidadeModel) As String - HttpPost - que permite tratar com o valor selecionado pelo cliente no dropdownlist;

3- Definindo a página para exibir as cidades - o View

As duas Actions, Index() e About(), do controlador expostas pela classe HomeController,  retornam uma view que contém o código HTML e o conteúdo que é enviado ao navegador; assim uma visão (view) é equivalente a uma página em uma aplicação ASP .NET MVC. Nosso exemplo temos a view Index.aspx e a view About.aspx.

Agora vamos usar a view Index.aspx que se encontra na pasta Home alterando o seu conteúdo conforme mostra o código a seguir:

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of IEnumerable (Of PreenchendoDropDownlist.Contato))" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2
> Relação das Capitais Brasileiras</h2>
<p>
  <label for="nome">
Selecione a Cidade :</label>
</p>
<%= Html.DropDownList("CidadeNome", DirectCast(ViewBag.CidadeLista, IEnumerable(Of SelectListItem)))%>
<input type="Submit" value="Enviar" />
</asp:Content>

Neste código estamos usando o controle DropDownList fornecido pelo Helper HtmlDropDownList.

Este helper possui a seguinte assinatura: Html.DropDownList(string name, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes)

Onde temos:

No nosso exemplo estamos usando o código abaixo:

<%= Html.DropDownList("CidadeNome", DirectCast(ViewBag.CidadeLista, IEnumerable(Of SelectListItem)))%>

Onde o nome do elemento esta sendo definido na propriedade ViewBag e a lista de itens é do um SelectListItem do tipo IEnumerable.

Executando o projeto iremos obter o seguinte resultado:

Como funciona ?

Se você esta iniciando agora com a tecnologia ASP .NET MVC ou vindo do mundo Web Forms pode não entender qual o fluxo de processamento foi realizado no projeto exemplo.

O fluxo segue o padrão MVC que pode ser descrito da seguinte forma:

  1. O usuário interage com a interface de alguma forma (por exemplo, o usuário clique em um botão)
  2. O Controller manipula o evento da interface do usuário através de uma rotina pré-escrita.
  3. O Controller acessa o Model, possivelmente atualizando-o de uma maneira apropriada, baseado na interação do usuário (por exemplo, atualizando os dados de cadastro do usuário).
  4. Algumas implementações de View utilizam o Model para gerar uma interface apropriada (por exemplo, mostrando na tela os dados que foram alterados juntamente com uma confirmação).
    O View obtém seus próprios dados do Model. O Model não toma conhecimento direto da View.
  5. A interface do usuário espera por próximas interações, que iniciarão o ciclo novamente.

Se você pretende criar aplicações ASP .NET MVC tem que se acostumar a pensar diferente pois uma URL não é igual a uma página...

Quando você cria uma aplicação ASP .NET no modelo tradicional usando Web Forms existe uma correspondência direta e única entre uma página e uma URL. Dessa forma, usando este modelo de desenvolvimento,  se você faz uma requisição para uma página chamada Exemplo.aspx, ela deve existir fisicamente no servidor ou caso contrário você irá receber como resposta a mensagem de erro : 404 - Page Not Found.

Ao desenvolver sua aplicação usando o modelo ASP .NET MVC  não existe uma correspondência entre uma URL e uma página, assim , a URL que é invocada pelo navegador  não esta relacionada com a presença obrigatória de arquivos físicos no servidor para exibição do resultado esperado.

Agora preste atenção nesta assertiva:  No modelo de desenvolvimento ASP .NET MVC uma URL corresponde a um ação de um Controller(Controller Action) e não a uma página em disco.

Dessa forma quando iniciamos a nossa aplicação o controlador HomeController.vb será acionado e o método Index() executado primeiro o HttpGet e depois o HttPost.

O método Index() que irá acionar a View representada pela página Index.aspx que irá obter a lista de cidades do Model.

O mapeamento que determina esse comportamento esta presente no arquivo Global.asax que esta presente na raiz do projeto. Neste arquivo o método RegisterRoutes possui a rota padrão conforme mostrada abaixo:

 Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

        ' MapRoute takes the following parameters, in order:
        ' (1) Route name
        ' (2) URL with parameters
        ' (3) Parameter defaults
        routes.MapRoute( _
            "Default", _
            "{controller}/{action}/{id}", _
            New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional}
_
        )

    End Sub

Assim, quando uma aplicação ASP .NET é iniciada pela primeira vez o método Application_Start() é chamado, e, pelo código acima vemos que este método chama o método  RegisterRoutes(RouteTable.Routes),  e este método cria a tabela de rotas padrão.

A tabela de rotas padrão possui uma rota , e , esta rota padrão divide todas as requisições de entrada em três segmentos:("{controller}/{action}/{id}",)   

Resumindo em uma aplicação ASP .NET MVC sempre teremos:

  1. Uma View que deverá conter somente a lógica relacionada com a geração da interface com o usuário
  2. Um Controller que deverá conter somente a retornar a view correta ou redirecionar o usuário para outra ação.
  3. O Model que deverá conter toda a lógica de negócio restante.

Pegue o projeto completo aqui: PreenchendoDropDownlist.zip

Mar 1:18 Então eles, deixando imediatamente as suas redes, o seguiram.

Mar 1:19 E ele, passando um pouco adiante, viu Tiago, filho de Zebedeu, e João, seu irmão, que estavam no barco, consertando as redes,

Mar 1:20 e logo os chamou; eles, deixando seu pai Zebedeu no barco com os empregados, o seguiram.

Mar 1:21 Entraram em Cafarnaum; e, logo no sábado, indo ele à sinagoga, pôs-se a ensinar.

Mar 1:22 E maravilhavam-se da sua doutrina, porque os ensinava como tendo autoridade, e não como os escribas.

Referências:


José Carlos Macoratti