Condividi tramite


Introduzione alla Pagine Web ASP.NET - Immissione di dati del database tramite moduli

di Tom FitzMacken

Questa esercitazione illustra come creare un modulo di voce e quindi immettere i dati che si ottengono dal modulo in una tabella di database quando si usa Pagine Web ASP.NET (Razor). Si presuppone che sia stata completata la serie tramite Nozioni di base dei moduli HTML in Pagine Web ASP.NET.

Contenuto dell'esercitazione:

  • Altre informazioni su come elaborare i moduli di immissione.
  • Come aggiungere (inserire) dati in un database.
  • Come assicurarsi che gli utenti abbiano immesso un valore obbligatorio in un modulo (come convalidare l'input utente).
  • Come visualizzare gli errori di convalida.
  • Come passare a un'altra pagina dalla pagina corrente.

Funzionalità/tecnologie illustrate:

  • Metodo Database.Execute .
  • Istruzione SQL Insert Into
  • Helper Validation .
  • Metodo Response.Redirect .

Scopo dell'esercitazione

Nell'esercitazione precedente che ha illustrato come creare un database, sono stati immessi i dati del database modificando il database direttamente in WebMatrix, lavorando nell'area di lavoro Database . Nella maggior parte delle app, tuttavia, non è un modo pratico per inserire i dati nel database. In questa esercitazione verrà quindi creata un'interfaccia basata sul Web che consente a chiunque di immettere i dati e salvarli nel database.

Si creerà una pagina in cui è possibile immettere nuovi film. La pagina conterrà un modulo di voce con campi (caselle di testo) in cui è possibile immettere un titolo, un genere e un anno. La pagina sarà simile alla seguente:

Pagina 'Aggiungi film' nel browser

Le caselle di testo saranno elementi HTML <input> che avranno un aspetto simile al markup seguente:

<input type="text" name="genre" value="" />

Creazione del modulo di voce di base

Creare una pagina denominata AddMovie.cshtml.

Sostituire il file con il markup seguente. Sovrascrivere tutto; si aggiungerà un blocco di codice nella parte superiore a breve.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Add a Movie</title>
</head>
<body>
  <h1>Add a Movie</h1>
  <form method="post">
    <fieldset>
      <legend>Movie Information</legend>
      <p><label for="title">Title:</label>
         <input type="text" name="title" value="@Request.Form["title"]" />
      </p>

      <p><label for="genre">Genre:</label>
         <input type="text" name="genre" value="@Request.Form["genre"]" />
      </p>

      <p><label for="year">Year:</label>
         <input type="text" name="year" value="@Request.Form["year"]" />
      </p>

      <p><input type="submit" name="buttonSubmit" value="Add Movie" /></p>
    </fieldset>
  </form>
</body>
</html>

In questo esempio viene illustrato il codice HTML tipico per la creazione di un modulo. Usa <input> gli elementi per le caselle di testo e per il pulsante invia. Le didascalie per le caselle di testo vengono create usando elementi standard <label> . Gli <fieldset> elementi e <legend> inserisce una bella scatola intorno al modulo.

Si noti che in questa pagina l'elemento <form> usa post come valore per l'attributo method . Nell'esercitazione precedente è stato creato un modulo che ha usato il get metodo . È stato corretto, perché anche se il modulo ha inviato valori al server, la richiesta non ha apportato modifiche. Tutto ciò che ha fatto è stato recuperare i dati in modi diversi. Tuttavia, in questa pagina verranno apportate modifiche: si aggiungeranno nuovi record di database. Pertanto, questo modulo deve usare il post metodo . Per altre informazioni sulla differenza tra GET e POST operazioni, vedere la barra lateraleGET, POST e HTTP Verb Safety nell'esercitazione precedente.

Si noti che ogni casella di testo ha un name elemento (title, , genreyear). Come si è visto nell'esercitazione precedente, questi nomi sono importanti perché è necessario disporre di tali nomi in modo da poter ottenere l'input dell'utente in un secondo momento. È possibile usare qualsiasi nome. È utile usare nomi significativi che consentono di ricordare i dati usati.

L'attributo value di ogni <input> elemento contiene un bit di codice Razor , ad esempio Request.Form["title"]. Si è appresa una versione di questo trucco nell'esercitazione precedente per mantenere il valore immesso nella casella di testo (se presente) dopo l'invio del modulo.

Recupero dei valori del modulo

Aggiungere quindi codice che elabora il modulo. Nella struttura si eseguiranno le operazioni seguenti:

  1. Controllare se la pagina viene pubblicata (è stata inviata). Si vuole eseguire il codice solo quando gli utenti hanno fatto clic sul pulsante, non quando la pagina viene eseguita per la prima volta.
  2. Ottenere i valori immessi dall'utente nelle caselle di testo. In questo caso, poiché il modulo usa il POST verbo, si ottengono i valori del modulo dalla Request.Form raccolta.
  3. Inserire i valori come nuovo record nella tabella di database Movies .

Nella parte superiore del file aggiungere il codice seguente:

@{
    var title = "";
    var genre = "";
    var year = "";

    if(IsPost){
        title = Request.Form["title"];
        genre = Request.Form["genre"];
        year = Request.Form["year"];
    }
}

Le prime righe creano variabili (title, genree year) per contenere i valori dalle caselle di testo. La riga if(IsPost) assicura che le variabili siano impostate solo quando gli utenti fanno clic sul pulsante Aggiungi film , ovvero quando il modulo è stato pubblicato.

Come si è visto in un'esercitazione precedente, si ottiene il valore di una casella di testo usando un'espressione come Request.Form["name"], dove nome è il nome dell'elemento <input> .

I nomi delle variabili (title, genree ) yearsono arbitrari. Come i nomi che si assegnano agli <input> elementi, è possibile chiamarli tutto quello che ti piace. I nomi delle variabili non devono corrispondere agli attributi dei nomi degli <input> elementi nel modulo. Ma come con gli <input> elementi, è consigliabile usare nomi di variabili che riflettono i dati che contengono. Quando si scrive codice, i nomi coerenti semplificano la memorizzazione dei dati usati.

Aggiunta di dati al database

Nel blocco di codice appena aggiunto, all'interno della parentesi graffe di chiusura ( } ) del blocco (non solo all'interno del if blocco di codice), aggiungere il codice seguente:

var db = Database.Open("WebPagesMovies");
var insertCommand = "INSERT INTO Movies (Title, Genre, Year) VALUES(@0, @1, @2)";
db.Execute(insertCommand, title, genre, year);

Questo esempio è simile al codice usato in un'esercitazione precedente per recuperare e visualizzare i dati. La riga che inizia con db = apre il database, come prima, e la riga successiva definisce un'istruzione SQL, di nuovo come si è visto prima. Tuttavia, questa volta definisce un'istruzione SQL Insert Into . Nell'esempio seguente viene illustrata la sintassi generale dell'istruzione Insert Into :

INSERT INTO table (column1, column2, column3, ...) VALUES (value1, value2, value3, ...)

In altre parole, specificare la tabella da inserire, quindi elencare le colonne da inserire e quindi elencare i valori da inserire. Come indicato in precedenza, SQL non è distinzione tra maiuscole e minuscole, ma alcune persone maiuscole e minuscole per semplificare la lettura del comando.

Le colonne inserite in sono già elencate nel comando - (Title, Genre, Year). La parte interessante è come ottenere i valori dalle caselle di testo nella VALUES parte del comando. Anziché valori effettivi, viene visualizzato @0, @1e @2, che sono segnaposto di corso. Quando si esegue il comando (nella db.Execute riga), si passano i valori provenienti dalle caselle di testo.

Importante! Tenere presente che l'unico modo per includere i dati immessi online da un utente in un'istruzione SQL consiste nell'usare i segnaposto, come illustrato qui (VALUES(@0, @1, @2)). Se si concatena l'input utente in un'istruzione SQL, si apre un attacco sql injection, come illustrato in Nozioni di base del modulo in Pagine Web ASP.NET (esercitazione precedente).

Ancora all'interno del if blocco aggiungere la riga seguente dopo la db.Execute riga:

Response.Redirect("~/Movies");

Dopo che il nuovo film è stato inserito nel database, questa riga salta (reindirizza) alla pagina Film in modo da poter visualizzare il film appena immesso. L'operatore ~ indica "radice del sito Web". L'operatore ~ funziona solo nelle pagine ASP.NET, non in genere in HTML.

Il blocco di codice completo è simile all'esempio seguente:

@{
    var title = "";
    var genre = "";
    var year = "";

    if(IsPost){
        title = Request.Form["title"];
        genre = Request.Form["genre"];
        year = Request.Form["year"];

        var db = Database.Open("WebPagesMovies");
        var insertCommand = "INSERT INTO Movies (Title, Genre, Year) Values(@0, @1, @2)";
        db.Execute(insertCommand, title, genre, year);
        Response.Redirect("~/Movies");
    }
}

Test del comando Inserisci (finora)

Non è ancora stato fatto, ma ora è un buon momento per testare.

Nella visualizzazione albero dei file in WebMatrix fare clic con il pulsante destro del mouse sulla pagina AddMovie.cshtml e quindi scegliere Avvia nel browser.

Screenshot che mostra la pagina

Se si finisce con una pagina diversa nel browser, assicurarsi che l'URL sia ), dove nnnnn è http://localhost:nnnnn/AddMovieil numero di porta usato.

È stata visualizzata una pagina di errore? In tal caso, leggerlo attentamente e assicurarsi che il codice sia esattamente quello elencato in precedenza.

Immettere un film nel modulo, ad esempio usare "Citizen Kane", "Drama" e "1941". (O qualsiasi cosa).) Fare quindi clic su Aggiungi filmato.

Se tutto va bene, si viene reindirizzati alla pagina Film . Assicurarsi che il nuovo film sia elencato.

Pagina film che mostra il filmato appena aggiunto

Convalida dell'input utente

Indietro alla pagina AddMovie o eseguirla di nuovo. Immettere un altro film, ma questa volta immettere solo il titolo, ad esempio immettere "Singin' in Pioggia". Fare quindi clic su Aggiungi filmato.

Si viene reindirizzati di nuovo alla pagina Film . È possibile trovare il nuovo film, ma è incompleto.

Pagina film che mostra un nuovo filmato mancante di alcuni valori

Quando si crea la tabella Movies , si dice in modo esplicito che nessuno dei campi potrebbe essere null. Qui hai un modulo di immissione per nuovi film e stai lasciando campi vuoti. Si tratta di un errore.

In questo caso, il database non ha effettivamente generato (o generato) un errore. Non è stato fornito un genere o un anno, quindi il codice nella pagina AddMovie ha considerato tali valori come stringhe vuote. Quando il comando SQL Insert Into è stato eseguito, i campi di genere e anno non hanno dati utili in essi, ma non erano null.

Ovviamente, non si vuole consentire agli utenti di immettere informazioni sui film metà vuote nel database. La soluzione consiste nel convalidare l'input dell'utente. Inizialmente, la convalida garantisce semplicemente che l'utente abbia immesso un valore per tutti i campi, ovvero che nessuno di essi contiene una stringa vuota.

Suggerimento

Stringhe null e vuote

Nella programmazione esiste una distinzione tra diverse nozioni di "nessun valore". In generale, un valore è Null se non è mai stato impostato o inizializzato in alcun modo. Al contrario, una variabile che prevede dati di carattere (stringhe) può essere impostata su una stringa vuota. In questo caso, il valore non è Null; è stato appena impostato in modo esplicito su una stringa di caratteri la cui lunghezza è zero. Queste due istruzioni mostrano la differenza:

var firstName;       // Not set, so its value is null
var firstName = "";  // Explicitly set to an empty string -- not null

È un po' più complicato di questo, ma il punto importante è che null rappresenta un tipo di stato indeterminato.

Ora e quindi è importante comprendere esattamente quando un valore è Null e quando è solo una stringa vuota. Nel codice della pagina AddMovie si ottengono i valori delle caselle di testo usando Request.Form["title"] e così via. Quando la pagina viene eseguita prima di fare clic sul pulsante, il valore di Request.Form["title"] è Null. Ma quando si invia il modulo, Request.Form["title"] ottiene il valore della title casella di testo. Non è ovvio, ma una casella di testo vuota non è Null; ha solo una stringa vuota in esso. Quindi, quando il codice viene eseguito in risposta al clic del pulsante, Request.Form["title"] ha una stringa vuota in esso.

Perché questa distinzione è importante? Quando si crea la tabella Movies , si dice in modo esplicito che nessuno dei campi potrebbe essere null. Ma qui hai un modulo di immissione per nuovi film e stai lasciando i campi vuoti. Si prevede ragionevolmente che il database si lamenta quando si tenta di salvare nuovi film che non hanno valori per genere o anno. Ma questo è il punto , anche se si lasciano vuote le caselle di testo, i valori non sono Null; sono stringhe vuote. Di conseguenza, è possibile salvare nuovi film nel database con queste colonne vuote, ma non null! - valori. Pertanto, è necessario assicurarsi che gli utenti non inviino una stringa vuota, che è possibile eseguire convalidando l'input dell'utente.

Helper di convalida

Pagine Web ASP.NET include un helper, l'helperValidation, che è possibile usare per assicurarsi che gli utenti immettono i dati che soddisfano i requisiti. L'helper Validation è uno degli helper compilati per Pagine Web ASP.NET, quindi non è necessario installarlo come pacchetto usando NuGet, il modo in cui è stato installato l'helper Gravatar in un'esercitazione precedente.

Per convalidare l'input dell'utente, si eseguiranno le operazioni seguenti:

  • Usare il codice per specificare che si desidera richiedere valori nelle caselle di testo nella pagina.
  • Inserire un test nel codice in modo che le informazioni sui film vengano aggiunte al database solo se tutto convalida correttamente.
  • Aggiungere codice al markup per visualizzare i messaggi di errore.

Nel blocco di codice nella pagina AddMovie , in alto nella parte superiore prima delle dichiarazioni delle variabili, aggiungere il codice seguente:

Validation.RequireField("title", "You must enter a title");
Validation.RequireField("genre", "Genre is required");
Validation.RequireField("year", "You haven't entered a year");

Si chiama Validation.RequireField una volta per ogni campo (<input> elemento) in cui si vuole richiedere una voce. È anche possibile aggiungere un messaggio di errore personalizzato per ogni chiamata, come illustrato qui. (I messaggi sono stati variati solo per mostrare che è possibile mettere qualsiasi cosa che ti piace lì).

Se si verifica un problema, si vuole impedire l'inserimento delle nuove informazioni sui film nel database. if(IsPost) Nel blocco usare && (logico AND) per aggiungere un'altra condizione che verifica Validation.IsValid(). Al termine, l'intero if(IsPost) blocco è simile al codice seguente:

if(IsPost && Validation.IsValid()){
    title = Request.Form["title"];
    genre = Request.Form["genre"];
    year = Request.Form["year"];

    var db = Database.Open("WebPagesMovies");
    var insertCommand = "INSERT INTO Movies (Title, Genre, Year) Values(@0, @1, @2)";
    db.Execute(insertCommand, title, genre, year);
    Response.Redirect("~/Movies");
}

Se si verifica un errore di convalida con uno dei campi registrati usando l'helper Validation , il Validation.IsValid metodo restituisce false. In questo caso, nessuno del codice in tale blocco verrà eseguito, quindi non verranno inserite voci di film non valide nel database. E naturalmente non sei reindirizzato alla pagina Film .

Il blocco di codice completo, incluso il codice di convalida, è ora simile al seguente:

@{
    Validation.RequireField("title", "You must enter a title");
    Validation.RequireField("genre", "Genre is required");
    Validation.RequireField("year", "You haven't entered a year");

    var title = "";
    var genre = "";
    var year = "";

    if(IsPost && Validation.IsValid()){
       title = Request.Form["title"];
       genre = Request.Form["genre"];
       year = Request.Form["year"];

       var db = Database.Open("WebPagesMovies");
       var insertCommand = "INSERT INTO Movies (Title, Genre, Year) Values(@0, @1, @2)";
       db.Execute(insertCommand, title, genre, year);
       Response.Redirect("~/Movies");
    }
}

Visualizzazione degli errori di convalida

L'ultimo passaggio consiste nel visualizzare eventuali messaggi di errore. È possibile visualizzare singoli messaggi per ogni errore di convalida oppure visualizzare un riepilogo o entrambi. Per questa esercitazione, si eseguiranno entrambe in modo che sia possibile vedere come funziona.

Accanto a ogni <input> elemento che si sta convalidando, chiamare il Html.ValidationMessage metodo e passarlo il nome dell'elemento <input> che si sta convalidando. Si inserisce il metodo giusto in cui si vuole che venga visualizzato il Html.ValidationMessage messaggio di errore. Quando viene eseguita la pagina, il metodo esegue il Html.ValidationMessage rendering di un <span> elemento in cui verrà eseguito l'errore di convalida. Se non è presente alcun errore, l'elemento viene eseguito il <span> rendering, ma non c'è testo in esso.

Modificare il markup nella pagina in modo che includa un Html.ValidationMessage metodo per ognuno dei tre <input> elementi della pagina, ad esempio:

<p><label for="title">Title:</label>
     <input type="text" name="title" value="@Request.Form["title"]" />
      @Html.ValidationMessage("title")
  </p>

  <p><label for="genre">Genre:</label>
     <input type="text" name="genre" value="@Request.Form["genre"]" />
      @Html.ValidationMessage("genre")
  </p>

  <p><label for="year">Year:</label>
     <input type="text" name="year" value="@Request.Form["year"]" />
      @Html.ValidationMessage("year")
  </p>

Per visualizzare il funzionamento del riepilogo, aggiungere anche il markup e il codice seguenti subito dopo l'elemento <h1>Add a Movie</h1> nella pagina:

@Html.ValidationSummary()

Per impostazione predefinita, il Html.ValidationSummary metodo visualizza tutti i messaggi di convalida in un elenco (un <ul> elemento all'interno di un <div> elemento). Come per il Html.ValidationMessage metodo, il markup per il riepilogo di convalida viene sempre eseguito il rendering. Se non sono presenti errori, non vengono visualizzati elementi di elenco.

Il riepilogo può essere un modo alternativo per visualizzare i messaggi di convalida anziché usare il Html.ValidationMessage metodo per visualizzare ogni errore specifico del campo. In alternativa, è possibile usare sia un riepilogo che i dettagli. In alternativa, è possibile usare il Html.ValidationSummary metodo per visualizzare un errore generico e quindi usare singole Html.ValidationMessage chiamate per visualizzare i dettagli.

La pagina completa è ora simile all'esempio seguente:

@{
    Validation.RequireField("title", "You must enter a title");
    Validation.RequireField("genre", "Genre is required");
    Validation.RequireField("year", "You haven't entered a year");

    var title = "";
    var genre = "";
    var year = "";

    if(IsPost && Validation.IsValid()){
       title = Request.Form["title"];
       genre = Request.Form["genre"];
       year = Request.Form["year"];

       var db = Database.Open("WebPagesMovies");
       var insertCommand = "INSERT INTO Movies (Title, Genre, Year) Values(@0, @1, @2)";
       db.Execute(insertCommand, title, genre, year);
       Response.Redirect("~/Movies");
    }
}

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Add a Movie</title>
</head>
<body>
  <h1>Add a Movie</h1>
  @Html.ValidationSummary()
  <form method="post">
    <fieldset>
      <legend>Movie Information</legend>
      <p><label for="title">Title:</label>
         <input type="text" name="title" value="@Request.Form["title"]" />
          @Html.ValidationMessage("title")
      </p>

      <p><label for="genre">Genre:</label>
         <input type="text" name="genre" value="@Request.Form["genre"]" />
          @Html.ValidationMessage("genre")
      </p>

      <p><label for="year">Year:</label>
         <input type="text" name="year" value="@Request.Form["year"]" />
          @Html.ValidationMessage("year")
      </p>

      <p><input type="submit" name="buttonSubmit" value="Add Movie" /></p>
    </fieldset>
  </form>
</body>
</html>

È tutto. È ora possibile testare la pagina aggiungendo un filmato, ma lasciando fuori uno o più campi. Quando si esegue questa operazione, viene visualizzato l'errore seguente:

Pagina Aggiungi filmato che mostra i messaggi di errore di convalida

Stili dei messaggi di errore di convalida

È possibile notare che ci sono messaggi di errore, ma non sono davvero molto ben noti. È tuttavia possibile assegnare uno stile semplice ai messaggi di errore.

Per assegnare uno stile ai singoli messaggi di errore visualizzati da Html.ValidationMessage, creare una classe di stile CSS denominata field-validation-error. Per definire la ricerca del riepilogo della convalida, creare una classe di stile CSS denominata validation-summary-errors.

Per vedere come funziona questa tecnica, aggiungere un <style> elemento all'interno della <head> sezione della pagina. Definire quindi classi di stile denominate field-validation-error e validation-summary-errors che contengono le regole seguenti:

<head>
  <meta charset="utf-8" />
  <title>Add a Movie</title>
  <style type="text/css">
    .field-validation-error {
      font-weight:bold;
      color:red;
      background-color:yellow;
     }
    .validation-summary-errors{
      border:2px dashed red;
      color:red;
      background-color:yellow;
      font-weight:bold;
      margin:12px;
    }
  </style>
</head>

In genere si inseriscono le informazioni sullo stile in un file css separato, ma per semplicità è possibile inserirle nella pagina per il momento. Più avanti in questo set di esercitazioni si spostano le regole CSS in un file CSS separato.

Se si verifica un errore di convalida, il metodo esegue il Html.ValidationMessage rendering di un <span> elemento che include class="field-validation-error". Aggiungendo una definizione di stile per tale classe, è possibile configurare l'aspetto del messaggio. Se si verificano errori, il ValidationSummary metodo esegue in modo dinamico il rendering dell'attributo class="validation-summary-errors".

Eseguire di nuovo la pagina e lasciare fuori un paio di campi. Gli errori sono ora più evidenti. (Infatti, sono sovrascrivi, ma è solo per mostrare cosa si può fare.

Pagina Aggiungi filmato che mostra gli errori di convalida che sono stati stili

Un passaggio finale consiste nel rendere conveniente accedere alla pagina AddMovie dalla presentazione del film originale.

Aprire di nuovo la pagina Film . Dopo il tag di chiusura </div> che segue l'helper WebGrid , aggiungere il markup seguente:

<p>
  <a href="~/AddMovie">Add a movie</a>
</p>

Come si è visto in precedenza, ASP.NET interpreta l'operatore ~ come radice del sito Web. Non è necessario usare l'operatore. È possibile usare il ~ markup <a href="./AddMovie">Add a movie</a> o un altro modo per definire il percorso compreso da HTML. Tuttavia, l'operatore ~ è un approccio generale ottimale quando si creano collegamenti per le pagine Razor, perché rende il sito più flessibile, se si sposta la pagina corrente in una sottocartella, il collegamento passa comunque alla pagina AddMovie . Tenere presente che l'operatore ~ funziona solo nelle pagine con estensione cshtml . ASP.NET lo capisce, ma non è HTML standard.

Al termine, eseguire la pagina Film . Sarà simile alla pagina seguente:

Pagina Film con collegamento alla pagina

Fare clic sul collegamento Aggiungi un film per assicurarsi che vada alla pagina AddMovie .

Prossima ora

Nell'esercitazione successiva si apprenderà come consentire agli utenti di modificare i dati già presenti nel database.

Elenco completo per la pagina AddMovie

@{

    Validation.RequireField("title", "You must enter a title");
    Validation.RequireField("genre", "Genre is required");
    Validation.RequireField("year", "You haven't entered a year");

    var title = "";
    var genre = "";
    var year = "";

    if(IsPost && Validation.IsValid()){
       title = Request.Form["title"];
       genre = Request.Form["genre"];
       year = Request.Form["year"];

       var db = Database.Open("WebPagesMovies");
       var insertCommand = "INSERT INTO Movies (Title, Genre, Year) Values(@0, @1, @2)";
       db.Execute(insertCommand, title, genre, year);
       Response.Redirect("~/Movies");
    }
}

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Add a Movie</title>
      <style type="text/css">
    .field-validation-error {
      font-weight:bold;
      color:red;
      background-color:yellow;
     }
    .validation-summary-errors{
      border:2px dashed red;
      color:red;
      background-color:yellow;
      font-weight:bold;
      margin:12px;
    }
  </style>
</head>
<body>
  <h1>Add a Movie</h1>
  @Html.ValidationSummary()
  <form method="post">
    <fieldset>
      <legend>Movie Information</legend>
      <p><label for="title">Title:</label>
         <input type="text" name="title" value="@Request.Form["title"]" />
          @Html.ValidationMessage("title")
      </p>

      <p><label for="genre">Genre:</label>
         <input type="text" name="genre" value="@Request.Form["genre"]" />
         @Html.ValidationMessage("genre")
      </p>

      <p><label for="year">Year:</label>
         <input type="text" name="year" value="@Request.Form["year"]" />
          @Html.ValidationMessage("year")
      </p>

      <p><input type="submit" name="buttonSubmit" value="Add Movie" /></p>
    </fieldset>
  </form>
</body>
</html>

Risorse aggiuntive