Compartilhar via


Adicionar validação ao modelo (VB)

por Rick Anderson

Este tutorial ensinará os conceitos básicos da criação de um aplicativo Web MVC ASP.NET usando o Microsoft Visual Web Developer 2010 Express Service Pack 1, que é uma versão gratuita do Microsoft Visual Studio. Antes de começar, verifique se você instalou os pré-requisitos listados abaixo. Você pode instalar todos eles clicando no seguinte link: Web Platform Installer. Como alternativa, você pode instalar individualmente os pré-requisitos usando os seguintes links:

Se você estiver usando o Visual Studio 2010 em vez do Visual Web Developer 2010, instale os pré-requisitos clicando no seguinte link: Pré-requisitos do Visual Studio 2010.

Um projeto do Visual Web Developer com VB.NET código-fonte está disponível para acompanhar este tópico. Baixe a versão VB.NET. Se você preferir C#, mude para a versão C# deste tutorial.

Nesta seção, você adicionará lógica de validação ao Movie modelo e garantirá que as regras de validação sejam impostas sempre que um usuário tentar criar ou editar um filme usando o aplicativo.

Mantendo as coisas SECAS

Um dos princípios básicos de design do ASP.NET MVC é o DRY ("Don't Repeat Yourself"). ASP.NET MVC incentiva você a especificar a funcionalidade ou o comportamento apenas uma vez e, em seguida, fazer com que ele seja refletido em todos os lugares em um aplicativo. Isso reduz a quantidade de código que você precisa escrever e torna o código que você escreve muito mais fácil de manter.

O suporte de validação fornecido pelo MVC e ASP.NET pelo Entity Framework Code First é um ótimo exemplo do princípio DRY em ação. Você pode especificar declarativamente regras de validação em um só lugar (na classe de modelo) e, em seguida, essas regras são impostas em todos os lugares do aplicativo.

Vejamos como você pode aproveitar esse suporte de validação no aplicativo de filme.

Adicionando regras de validação ao modelo de filme

Você começará adicionando alguma lógica de validação à Movie classe.

Abra o arquivo Movie.vb . Adicione uma Imports instrução na parte superior do arquivo que faça referência ao System.ComponentModel.DataAnnotations namespace:

Imports System.ComponentModel.DataAnnotations

O namespace faz parte do .NET Framework. Ele fornece um conjunto interno de atributos de validação que você pode aplicar declarativamente a qualquer classe ou propriedade.

Agora, atualize a Movie classe para aproveitar os atributos internos Required, StringLength, e validation Range . Use o código a seguir como um exemplo de onde aplicar os atributos.

Public Class Movie
    Public Property ID() As Integer

    <Required(ErrorMessage:="Title is required")>
    Public Property Title() As String

    <Required(ErrorMessage:="Date is required")>
    Public Property ReleaseDate() As Date

    <Required(ErrorMessage:="Genre must be specified")>
    Public Property Genre() As String

    <Required(ErrorMessage:="Price Required"), Range(1, 100, ErrorMessage:="Price must be between $1 and $100")>
    Public Property Price() As Decimal

    <StringLength(5)>
    Public Property Rating() As String
End Class

Os atributos de validação especificam o comportamento que você deseja impor nas propriedades de modelo às quais eles são aplicados. O Required atributo indica que uma propriedade deve ter um valor; neste exemplo, um filme deve ter valores para as Titlepropriedades , ReleaseDate, Genre, e Price para ser válido. O atributo Range restringe um valor a um intervalo especificado. O atributo StringLength permite definir o tamanho máximo de uma propriedade de cadeia de caracteres e, opcionalmente, seu tamanho mínimo.

O Code First garante que as regras de validação especificadas em uma classe de modelo sejam impostas antes que o aplicativo salve as alterações no banco de dados. Por exemplo, o código abaixo lançará uma exceção quando o SaveChanges método for chamado, pois vários valores de propriedade necessários Movie estão ausentes e o preço é zero (que está fora do intervalo válido).

Dim db As New MovieDBContext()

Dim movie As New Movie()
movie.Title = "Gone with the Wind"
movie.Price = 0.0D

db.Movies.Add(movie)
db.SaveChanges() ' <= Will throw validation exception

Ter regras de validação impostas automaticamente pelo .NET Framework ajuda a tornar seu aplicativo mais robusto. Também garante que você não se esqueça de validar algo e inadvertidamente permita dados incorretos no banco de dados.

Aqui está uma lista de código completa para o arquivo Movie.vb atualizado:

Imports System.Data.Entity
Imports System.ComponentModel.DataAnnotations

Public Class Movie
    Public Property ID() As Integer

    <Required(ErrorMessage:="Title is required")>
    Public Property Title() As String

    <Required(ErrorMessage:="Date is required")>
    Public Property ReleaseDate() As Date

    <Required(ErrorMessage:="Genre must be specified")>
    Public Property Genre() As String

    <Required(ErrorMessage:="Price Required"), Range(1, 100, ErrorMessage:="Price must be between $1 and $100")>
    Public Property Price() As Decimal

    <StringLength(5)>
    Public Property Rating() As String
End Class

Public Class MovieDBContext
    Inherits DbContext
    Public Property Movies() As DbSet(Of Movie)
End Class

Interface do usuário de erro de validação no MVC ASP.NET

Execute novamente o aplicativo e navegue até a URL / Movies .

Clique no link Criar filme para adicionar um novo filme. Preencha o formulário com alguns valores inválidos e clique no botão Criar .

8_validationErrors

Observe como o formulário usou automaticamente uma cor de plano de fundo para realçar as caixas de texto que contêm dados inválidos e emitiu uma mensagem de erro de validação apropriada ao lado de cada uma. As mensagens de erro correspondem às cadeias de caracteres de erro especificadas quando anotou a Movie classe. Os erros são aplicados tanto no lado do cliente (usando JavaScript) quanto no lado do servidor (caso um usuário tenha o JavaScript desabilitado).

Um benefício real é que você não precisou alterar uma única linha de código na MoviesController classe ou na exibição Create.vbhtml para habilitar essa interface do usuário de validação. O controlador e as exibições que você criou anteriormente neste tutorial selecionaram automaticamente as regras de validação especificadas usando atributos na classe de Movie modelo.

Como a validação ocorre no modo de exibição Criar e no método de ação Criar

Talvez você esteja se perguntando como a interface do usuário de validação foi gerada sem atualizações do código no controlador ou nas exibições. A próxima listagem mostra a aparência dos Create métodos na MovieController classe. Eles permanecem inalterados em relação à forma como você os criou anteriormente neste tutorial.

'
' GET: /Movies/Create

Function Create() As ViewResult
    Return View()
End Function

'
' POST: /Movies/Create

<HttpPost()>
Function Create(movie As Movie) As ActionResult
    If ModelState.IsValid Then
        db.Movies.Add(movie)
        db.SaveChanges()
        Return RedirectToAction("Index")
    End If

    Return View(movie)
End Function

O primeiro método de ação exibe o formulário Criar inicial. O segundo lida com a postagem do formulário. O segundo Create método chama ModelState.IsValid para verificar se o filme tem algum erro de validação. A chamada a esse método avalia os atributos de validação que foram aplicados ao objeto. Se o objeto tiver erros de validação, o método exibirá Create novamente o formulário. Se não houver erros, o método salvará o novo filme no banco de dados.

Abaixo está o modelo de exibição Create.vbhtml que você scaffolded anteriormente no tutorial. Ela é usada pelos métodos de ação mostrados acima para exibir o formulário inicial e exibi-lo novamente em caso de erro.

@ModelType MvcMovie.Movie

@Code
    ViewData("Title") = "Create"
End Code

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@Using Html.BeginForm()
    @Html.ValidationSummary(True)
    @<fieldset>
        <legend>Movie</legend>

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

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

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

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

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

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

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

Observe como o código usa um Html.EditorFor auxiliar para gerar o <input> elemento para cada Movie propriedade. Ao lado desse auxiliar está uma chamada para o Html.ValidationMessageFor método auxiliar. Esses dois métodos auxiliares funcionam com o objeto de modelo que é passado pelo controlador para a exibição (nesse caso, um Movie objeto). Eles procuram automaticamente os atributos de validação especificados no modelo e exibem mensagens de erro conforme apropriado.

O que é realmente bom nessa abordagem é que nem o controlador nem o modelo de exibição Criar sabem nada sobre as regras de validação reais que estão sendo impostas ou sobre as mensagens de erro específicas exibidas. As regras de validação e as cadeias de caracteres de erro são especificadas somente na classe Movie.

Se você quiser alterar a lógica de validação posteriormente, poderá fazê-lo em exatamente um lugar. Você não precisa se preocupar se diferentes partes do aplicativo estão inconsistentes com a forma como as regras são impostas – toda a lógica de validação será definida em um lugar e usada em todos os lugares. Isso mantém o código muito limpo e torna-o mais fácil de manter e desenvolver. Além disso, isso significa que você respeitará totalmente o princípio DRY.

Adicionando formatação ao modelo de filme

Abra o arquivo Movie.vb . O namespace System.ComponentModel.DataAnnotations fornece atributos de formatação, além do conjunto interno de atributos de validação. Você aplicará o DisplayFormat atributo e um DataType valor de enumeração à data de lançamento e aos campos de preço. O código a seguir mostra as propriedades ReleaseDate e Price com o atributo DisplayFormat apropriado.

<DataType(DataType.Date)>
    Public Property ReleaseDate() As Date

     <DataType(DataType.Currency)>
    Public Property Price() As Decimal

Como alternativa, você pode definir explicitamente um DataFormatString valor. O código a seguir mostra a propriedade de data de lançamento com uma cadeia de caracteres de formato de data (ou seja, "d"). Você usaria isso para especificar que não deseja o tempo como parte da data de lançamento.

<DisplayFormat(DataFormatString:="{0:d}")>
    Public Property ReleaseDate() As Date

O código a seguir formata a Price propriedade como moeda.

<DisplayFormat(DataFormatString:="{0:c}")>
    Public Property Price() As Decimal

A classe completa Movie é mostrada abaixo.

Public Class Movie
    Public Property ID() As Integer

    <Required(ErrorMessage:="Title is required")>
    Public Property Title() As String

    <Required(ErrorMessage:="Date is required")>
    <DataType(DataType.Date)>
    Public Property ReleaseDate() As Date

    <Required(ErrorMessage:="Genre must be specified")>
    Public Property Genre() As String

    <Required(ErrorMessage:="Price Required"), Range(1, 100, ErrorMessage:="Price must be between $1 and $100")>
    <DataType(DataType.Currency)>
    Public Property Price() As Decimal

    <StringLength(5)>
    Public Property Rating() As String
End Class

Execute o aplicativo e navegue até o Movies controlador.

8_format_SM

Na próxima parte da série, revisaremos o aplicativo e faremos algumas melhorias nos métodos e Delete gerados Details automaticamente.