Motivação

O ASP.NET MVC tem sido utilizado pelos desenvolvedores web por diversos motivos. Um deles está relacionado à forma como o framework organiza os artefatos do projeto, facilitando o reuso de código. Nesse cenário, no que diz respeito às views (o “V” da sigla MVC), duas das principais ferramentas são os templates editor e display. Esses elementos são associados a um tipo (uma classe ou mesmo um tipo primitivo, como int e double) e servem para centralizar a forma como o Razor e o ASP.NET MVC renderizam os valores desse tipo para gerar campos de amostragem (display templates) e campos de entrada de dados (editor templates).

Qual a vantagem dos templateseditor e display?

Vamos imaginar a seguinte situação: você tem uma entidade (Produto, por exemplo) que é mostrada em diversas views:

  • View 1: página de detalhes do produto;
  • View 2: página de remoção do produto;
  • View 3: página de categorias contendo os produtos relacionados a ela;
  • View 4: página de detalhes da compra.

Caso consideremos que essas quatro views mostram os produtos, individualmente, da mesma forma, podemos centralizar tudo isso em um display template. Assim, se quisermos alterar a forma como eles são vistos, basta fazermos isso uma vez, no display template, e isso será replicado para todas views. Essa decisão possibilita um ganho de tempo em desenvolvimento muito grande, pois ao invés de repetir quatro vezes o processo, podemos realizá-lo apenas uma vez.

Display templates no ASP.NET MVC

Os display templates obedecem a uma estrutura rígida para que possam ser utilizados. Assim, há um diretório específico para que eles sejam guardados na solução, de forma que o MVC consiga encontrá-los quando necessário. Esse diretório está sempre em Views/Shared/DisplayTemplates, como podemos observar na Figura 1.

Diretório de display templates
Figura 1. Diretório de display templates

Algo muito importante a se ressaltar nessa imagem é o nome do template que acabamos de criar: Produto. Repare que é o mesmo nome da classe/entidade que temos na nossa aplicação.Isso é uma regra, uma convenção: para que o ASP.NET MVC entenda que o template deve ser utilizado para o tipo Produto, esse template precisa ter o mesmo nome do tipo. Dessa forma, para o tipo “string”, por exemplo, teríamos um arquivo nomeado como string.cshtml.

Na Listagem 1 é apresentado o código do template de Produto, Produto.cshtml. Como podemos observar, seu conteúdo é bastante simples: temos a amostragem das propriedades do Produto definidas de forma visualmente interessante, com algumas classes do Bootstrap.

Listagem 1. Display template para Produto

        @model ExemploDisplayEditor.Models.Produto

        <h4>Produto</h4>
        <hr/>
        <dlclass="dl-horizontal">
        <dt>
        @Html.DisplayNameFor(model =>model.Descricao)
        </dt>

        <dd>
        @Html.DisplayFor(model =>model.Descricao)
        </dd>

        <dt>
        @Html.DisplayNameFor(model =>model.Nome)
        </dt>

        <dd>
        @Html.DisplayFor(model =>model.Nome)
        </dd>

        <dt>
        @Html.DisplayNameFor(model =>model.Preco)
        </dt>

        <dd>
        @Html.DisplayFor(model =>model.Preco)
        </dd>

        </dl>
        
  • Linha 1: Definição do tipo para o template (Produto, neste caso);
  • Linhas 3 4: Cabeçalho do template, com uma indicação de que se trata de um Produto;
  • Linhas 6 a 8 e 10 a 12: Amostragem dos dados da propriedade Descricao. O método DisplayNameFor() mostrará o nome da propriedade (Descricao) e o método DisplayFor() mostrará o seu conteúdo;
  • Linhas 14 a 16, 18 a 20, 22 a 24 e 26 a 28: Mesma amostragem das linhas 6 a 8 e 10 a 12, mas agora para as propriedades Nome e Preco.

Para utilizar um template, existem alguns métodos disponíveis, como: Html.DisplayFor(), para uma propriedade específica; e Html.DisplayForModel(), para o model completo da view. São esses métodos que realizarão, primeiramente, a busca por um display template para o tipo de dado no diretório e, se não encontrarem, simplesmente optarão pelo padrão.Um exemplo de uso fica muito claro na Figura 2, que traz, lado a lado, as views Details e Delete, que adotam esse template de amostragem.

Note que tudo que há de comum entre essas views está estabelecido do display template, e esse é o grande ganho que ele traz para nós durante o desenvolvimento e manutenção de uma aplicação.

Details.cshtml e Delete.cshtml com o display template
Figura 2. Details.cshtml e Delete.cshtml com o display template

Editor templates no ASP.NET MVC

Os editor templates obedecem a uma lógica muito parecida. O diretório deles, entretanto, é outro: Views/Shared/EditorTemplates (vide Figura 3). É nesse local que o MVC irá procurar por esses templates no momento de renderizar uma view.

Diretório de editor templates
Figura 3. Diretório de editor templates

Aqui, devemos notar que o nome do arquivo para o editor template é o mesmo:Produto.cshtml. Isso ocorre porque as regras para os templates de edição são exatamente as mesmas, e devemos obedecê-las. O conteúdo, entretanto, é diferente, como apresenta a Listagem 2. Por se tratar de um template de edição, temos algumas diferenças, como a declaração de ValidationSummary, que serve para a validação dos valores inseridos nas propriedades.

Listagem 2. Editor template para Produto

        @model ExemploDisplayEditor.Models.Produto

        <h4>Produto</h4>
        <hr/>
        @Html.ValidationSummary(true, "", new{ @class = "text-danger" })
        <divclass="form-group">
        @Html.LabelFor(model =>model.Descricao, htmlAttributes: new{ @class = "control-label col-md-2" })
        <divclass="col-md-10">
        @Html.EditorFor(model =>model.Descricao, new{ htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model =>model.Descricao, "", new{ @class = "text-danger" })
        </div>
        </div>

        <divclass="form-group">
        @Html.LabelFor(model =>model.Nome, htmlAttributes: new{ @class = "control-label col-md-2" })
        <divclass="col-md-10">
        @Html.EditorFor(model =>model.Nome, new{ htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model =>model.Nome, "", new{ @class = "text-danger" })
        </div>
        </div>

        <divclass="form-group">
        @Html.LabelFor(model =>model.Preco, htmlAttributes: new{ @class = "control-label col-md-2" })
        <divclass="col-md-10">
        @Html.EditorFor(model =>model.Preco, new{ htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model =>model.Preco, "", new{ @class = "text-danger" })
        </div>
        </div>
        
  • Linha 1: Definição do tipo para o template: Produto;
  • Linhas 3 e 4: Cabeçalho do template, com uma indicação de que se trata de um Produto;
  • Linha 5: Criação do “sumário de validação”, ou ValidationSummary(). Esse elemento é necessário para que possamos ver as mensagens de validação para cada propriedade, quando houver algum erro nesses valores;
  • Linhas 6 a 12: Elementos de edição e visualização para a propriedade Descricao. Na linha 07, temos o LabelFor(), que simplesmente mostra o nome da propriedade acima do campo. Já na linha 9, temos o editor propriamente dito. Esse helper irá renderizar um elemento do tipo <input> para o campo;
  • Linhas 14 a 20 e 22 a 28: Mesmos editores das linhas 6 a 12, mas agora para as propriedades Nome e Preco.

O uso dos templates de edição também é muito similar ao que vimos para os display templates. Nesse caso, entretanto, temos dois outros métodos: EditorFor() e EditorForModel(). Eles farão a busca, agora no diretório EditorTemplates, pelo nome do tipo da propriedade; Produto, nesse caso. Caso não seja encontrado, voltarão com os valores padrão.

A Figura 4 mostra como podemos declarar nosso editor template em duas views: Create e Edit.

Create.cshtml e Edit.cshtml com o editor template
Figura 4. Create.cshtml e Edit.cshtml com o editor template
NOTA: É possível declarar outros nomes para os templates, como “ProdutoDisplay” ou “ProdutoEditor”, mas precisaríamos especificar esse nome no momento de sua utilização. Tanto os métodos DisplayFor() e DisplayForModel(), quanto os métodos EditorFor() e EditorForModel() possuem sobrecargas que recebem o nome do template; para esses casos, algo como DisplayForModel(“ProdutoDisplay”).

Com isso, podemos constatar que o uso dos templates editor e display possibilitam uma redução de trabalho ao desenvolver e/ou manter uma aplicação. Se tivéssemos que adicionar uma nova propriedade a Produto, por exemplo, bastaria uma alteração nos templates para que as views refletissem as mudanças,e isso é uma grande vantagem, especialmente em aplicações com diversas entidades e views.