Condividi tramite


Aggiunta della convalida al modello (VB)

di Rick Anderson

Questa esercitazione illustra le nozioni di base per la creazione di un'applicazione Web MVC ASP.NET con Microsoft Visual Web Developer 2010 Express Service Pack 1, una versione gratuita di Microsoft Visual Studio. Prima di iniziare, assicurarsi di aver installato i prerequisiti elencati di seguito. È possibile installarli tutti facendo clic sul collegamento seguente: Programma di installazione della piattaforma Web. In alternativa, è possibile installare singolarmente i prerequisiti usando i collegamenti seguenti:

Se si usa Visual Studio 2010 anziché Visual Web Developer 2010, installare i prerequisiti facendo clic sul collegamento seguente: Prerequisiti di Visual Studio 2010.

Per questo argomento è disponibile un progetto Visual Web Developer con VB.NET codice sorgente. Scaricare la versione VB.NET. Se si preferisce C#, passare alla versione C# di questa esercitazione.

In questa sezione si aggiungerà la logica di convalida al Movie modello e si assicurerà che le regole di convalida vengano applicate ogni volta che un utente tenta di creare o modificare un filmato usando l'applicazione.

Mantenere le cose DRY

Uno dei principali set di progettazione di ASP.NET MVC è DRY ("Non ripetere se stessi"). ASP.NET MVC incoraggia a specificare funzionalità o comportamento una sola volta e quindi rifletterla ovunque in un'applicazione. In questo modo si riduce la quantità di codice che è necessario scrivere e rende il codice molto più semplice da gestire.

Il supporto di convalida fornito da ASP.NET MVC ed Entity Framework Code First è un ottimo esempio del principio DRY in azione. È possibile specificare in modo dichiarativo le regole di convalida in un'unica posizione (nella classe modello) e quindi tali regole vengono applicate ovunque nell'applicazione.

Di seguito viene illustrato come sfruttare questo supporto per la convalida nell'applicazione film.

Aggiunta di regole di convalida al modello di film

Si inizierà aggiungendo una logica di convalida alla Movie classe .

Aprire il file Movie.vb . Aggiungere un'istruzione Imports all'inizio del file che fa riferimento allo System.ComponentModel.DataAnnotations spazio dei nomi :

Imports System.ComponentModel.DataAnnotations

Lo spazio dei nomi fa parte di .NET Framework. Fornisce un set predefinito di attributi di convalida che è possibile applicare in modo dichiarativo a qualsiasi classe o proprietà.

Aggiornare ora la Movie classe per sfruttare i vantaggi degli Requiredattributi di convalida predefiniti , StringLengthe Range . Usare il codice seguente come esempio di dove applicare gli attributi.

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

Gli attributi di convalida specificano il comportamento da applicare per le proprietà del modello a cui vengono applicati. L'attributo Required indica che una proprietà deve avere un valore. In questo esempio, un filmato deve avere valori per le Titleproprietà , GenreReleaseDate, e Price per essere valide. L'attributo Range vincola un valore all'interno di un intervallo specificato. L'attributo StringLength consente di impostare la lunghezza massima di una proprietà stringa e, facoltativamente, la lunghezza minima.

Code First garantisce che le regole di convalida specificate in una classe modello vengano applicate prima che l'applicazione salvi le modifiche nel database. Ad esempio, il codice seguente genererà un'eccezione quando viene chiamato il SaveChanges metodo , perché mancano diversi valori di proprietà obbligatori Movie e il prezzo è zero (che non rientra nell'intervallo valido).

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

La presenza di regole di convalida applicate automaticamente da .NET Framework consente di rendere l'applicazione più affidabile. In questo modo inoltre non è possibile omettere la convalida di un elemento e quindi inserire involontariamente dati errati nel database.

Ecco un elenco di codice completo per il file di Movie.vb aggiornato:

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

Interfaccia utente degli errori di convalida in ASP.NET MVC

Eseguire di nuovo l'applicazione e passare all'URL /Movies .

Fare clic sul collegamento Crea film per aggiungere un nuovo film. Compilare il modulo con alcuni valori non validi e quindi fare clic sul pulsante Crea .

8_validationErrors

Si noti che il modulo ha utilizzato automaticamente un colore di sfondo per evidenziare le caselle di testo che contengono dati non validi e ha generato un messaggio di errore di convalida appropriato accanto a ognuno di essi. I messaggi di errore corrispondono alle stringhe di errore specificate quando è stata annotata la Movie classe . Gli errori vengono applicati sia sul lato client (usando JavaScript) che sul lato server (nel caso in cui un utente abbia disabilitato JavaScript).

Un vantaggio reale è che non è necessario modificare una singola riga di codice nella MoviesController classe o nella visualizzazione Create.vbhtml per abilitare questa interfaccia utente di convalida. Il controller e le visualizzazioni create in precedenza in questa esercitazione hanno selezionato automaticamente le regole di convalida specificate usando gli attributi nella Movie classe modello.

Modalità di esecuzione della convalida nel metodo Crea visualizzazione e Crea azione

Ci si potrebbe chiedere come la convalida dell'interfaccia utente sia stata generata senza aggiornamenti al codice nel controller o nelle viste. L'elenco successivo mostra l'aspetto dei Create metodi nella MovieController classe . Sono invariati rispetto al modo in cui sono stati creati in precedenza in questa esercitazione.

'
' 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

Il primo metodo di azione visualizza il modulo Create iniziale. Il secondo gestisce il post del modulo. Il secondo Create metodo chiama ModelState.IsValid per verificare se il filmato presenta errori di convalida. La chiamata a questo metodo valuta tutti gli attributi di convalida applicati all'oggetto. Se l'oggetto presenta errori di convalida, il Create metodo riproduce il modulo. Se non sono presenti errori, il metodo salva il nuovo film nel database.

Di seguito è riportato il modello di visualizzazione Create.vbhtml di cui è stato eseguito lo scaffolding in precedenza nell'esercitazione. Viene usata dai metodi di azione illustrati in precedenza per visualizzare il modulo iniziale e per visualizzarlo nuovamente in caso di errore.

@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>

Si noti che il codice usa un Html.EditorFor helper per restituire l'elemento <input> per ogni Movie proprietà. Accanto a questo helper è una chiamata al Html.ValidationMessageFor metodo helper. Questi due metodi helper funzionano con l'oggetto modello passato dal controller alla visualizzazione (in questo caso, un Movie oggetto ). Cercano automaticamente gli attributi di convalida specificati nel modello e visualizzano i messaggi di errore in base alle esigenze.

Ciò che è davvero interessante di questo approccio è che né il controller né il modello di visualizzazione Crea sanno nulla sulle regole di convalida effettive applicate o sui messaggi di errore specifici visualizzati. Le regole di convalida e le stringhe di errore vengono specificate solo nella classe Movie.

Se si vuole modificare la logica di convalida in un secondo momento, è possibile farlo in un'unica posizione. Non è necessario preoccuparsi dell'incoerenza delle diverse parti dell'applicazione con la modalità di applicazione delle regole perché tutta la logica di convalida verrà definita in un'unica posizione e usata ovunque. In questo modo il codice rimane molto pulito e facile da gestire e sviluppare. Il principio DRY sarà ampiamente rispettato.

Aggiunta della formattazione al modello di film

Aprire il file Movie.vb . Lo spazio dei nomi System.ComponentModel.DataAnnotations fornisce gli attributi di formattazione oltre al set predefinito di attributi di convalida. Si applicherà l'attributo DisplayFormat e un DataType valore di enumerazione alla data di rilascio e ai campi prezzo. Il codice seguente illustra le proprietà ReleaseDate e Price con l'attributo appropriato DisplayFormat.

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

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

In alternativa, è possibile impostare in modo esplicito un DataFormatString valore. Il codice seguente mostra la proprietà data di rilascio con una stringa di formato data (vale a dire "d"). Usare questa opzione per specificare che non si vuole eseguire l'ora come parte della data di rilascio.

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

Il codice seguente formatta la Price proprietà come valuta.

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

La classe completa Movie è illustrata di seguito.

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

Eseguire l'applicazione e passare al Movies controller.

8_format_SM

Nella parte successiva della serie verrà esaminata l'applicazione e verranno apportati alcuni miglioramenti ai metodi e Delete generati Details automaticamente.