Cenário

Algo que eu considero bastante trabalhoso no desenvolvimento com Web Forms, é persistir campos de relacionamentos. Não que seja difícil, mas exige tempo e código repetitivo.

Se você não está lembrando deles, estou falando daqueles DropDowns que todo sistema deve ter e que muitas vezes se repetem no projeto e consequentemente temos que repetir também alguns fragmentos de códigos.

Boas Novas

O frameowork ASP.NET MVC trás algumas facilidades para minimizarmos esse problema: o atributo UIHint. Com ele podemos marcar em nosso modelo que determinado campo irá se comportar como um DropDownList e toda sua lógica ficará embutida num único local. Que tal?

Passo-a-Passo

Na nossa demonstração teremos “Equipes” e “Jogadores”. Cada equipe pode ter N jogadores e um jogador se associa a apenas uma equipe.

1) Inicialmente nosso modelo ficaria assim:

public class Equipe
{
    public int Codigo { get; set; }
    public string Nome { get; set; }
}

public class Jogador
{
    public int Codigo { get; set; }
    public string Nome { get; set; }
    public int CodigoEquipe { get; set; }
}

2) Veja que o objeto jogador depende de uma equipe. E na nossa interface precisamos de um DropDown para carregar o DataSource e permitir que o usuário selecione a equipe desejada.

Marcamos então, a propriedades com duas Data Annotations. São eles “UIHint” e “DisplayName”:

public class Equipe
{
    public int Codigo { get; set; }
    public string Nome { get; set; }
}

public class Jogador
{
    public int Codigo { get; set; }
    public string Nome { get; set; }

    [DisplayName("Equipe")]
    [UIHint("EquipeDropDown")]
    public int CodigoEquipe { get; set; }
}

Como esses atributos estão em outro namespace referencie System.ComponentModel.DataAnnotations e System.ComponentModel.

Viu que o atributo “UIHint” recebe a string “EquipeDropDown”? Esse é o nome da View que representa apenas o controle para manipulação dessa propriedade.

3) Crie uma View semelhante a essa dentro de “/Views/Shared/EditorTemplates/”:

@using Mvc3.Models

@{ 
    //
    // Estes elementos poderiam vir de qualquer DataSource
    //   
    var list = new[] { 
            new Equipe { Codigo = 1, Nome = "São Paulo" },
            new Equipe { Codigo = 2, Nome = "Atlético" },
            new Equipe { Codigo = 3, Nome = "Cruzeiro" },
            new Equipe { Codigo = 4, Nome = "Palmeiras" },
        };

    var selecList = new SelectList(list, "Codigo", "Nome", Model);
}

@Html.DropDownListFor(model => model, selecList, "[Selecione]")

Essa view possui esse código para carregamento do DropDown e nada mais. Você poderia simplificá-la deixando o carregamento da lista em uma camada separada (para o nosso objetivo isso não é tão importante).

Agora a View de cadastro:

@model Mvc3.Models.Jogador

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Jogador</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Codigo)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Codigo)
            @Html.ValidationMessageFor(model => model.Codigo)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Nome)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Nome)
            @Html.ValidationMessageFor(model => model.Nome)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.CodigoEquipe)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.CodigoEquipe)
            @Html.ValidationMessageFor(model => model.CodigoEquipe)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Veja que a página renderiza entende que aquele campo “CodigoEquipe” deve ser renderizado como um DropDown.

image

Agora ficou fácil pois o binding da propriedade com o objeto é feito pelo MVC e você pode recuperar a propriedade dentro da sua Action:

image

Simples não é? E você pode fazer isso para campos mais complexos do seu projeto e deixá-los disponíveis.