Introduzione a Pagine Web ASP.NET - Aggiornamento dei dati del database
Questa esercitazione illustra come aggiornare (modificare) una voce di database esistente quando si usa Pagine Web ASP.NET (Razor). Presuppone che la serie sia stata completata tramite l'immissione di dati tramite moduli tramite Pagine Web ASP.NET.
Contenuto dell'esercitazione:
- Come selezionare un singolo record nell'helper
WebGrid
.- Come leggere un singolo record da un database.
- Come precaricare un modulo con valori dal record del database.
- Come aggiornare un record esistente in un database.
- Come archiviare le informazioni nella pagina senza visualizzarla.
- Come usare un campo nascosto per archiviare le informazioni.
Funzionalità/tecnologie descritte:
- Helper
WebGrid
.- Comando SQL
Update
.- Metodo
Database.Execute
.- Campi nascosti (
<input type="hidden">
).
Scopo dell'esercitazione
Nell'esercitazione precedente si è appreso come aggiungere un record a un database. In questa sezione si apprenderà come visualizzare un record per la modifica. Nella pagina Film aggiornerai l'helper WebGrid
in modo che visualizzi un collegamento Modifica accanto a ogni filmato:
Quando si fa clic sul collegamento Modifica , si passa a una pagina diversa, in cui le informazioni sui film sono già in un modulo:
È possibile modificare uno qualsiasi dei valori. Quando invii le modifiche, il codice nella pagina aggiorna il database e ti riporta alla presentazione di film.
Questa parte del processo funziona quasi esattamente come la pagina AddMovie.cshtml creata nell'esercitazione precedente, così gran parte di questa esercitazione sarà familiare.
Esistono diversi modi per implementare un modo per modificare un singolo film. L'approccio illustrato è stato scelto perché è facile da implementare e comprendere facilmente.
Aggiunta di un collegamento di modifica alla presentazione di film
Per iniziare, aggiornerai la pagina Film in modo che ogni elenco di film contenga anche un collegamento Modifica .
Aprire il file Movies.cshtml .
Nel corpo della pagina modificare il WebGrid
markup aggiungendo una colonna. Ecco il markup modificato:
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year")
)
)
La nuova colonna è la seguente:
grid.Column(format: @<a href="~/EditMovie?id=@item.ID)">Edit</a>)
Il punto di questa colonna consiste nel mostrare un collegamento (<a>
elemento) il cui testo è "Modifica". Dopo è necessario creare un collegamento simile al seguente quando viene eseguita la pagina, con il id
valore diverso per ogni filmato:
http://localhost:43097/EditMovie?id=7
Questo collegamento richiamerà una pagina denominata EditMovie e passerà la stringa ?id=7
di query a tale pagina.
La sintassi per la nuova colonna potrebbe sembrare un po' complessa, ma questo è solo perché raggruppa diversi elementi. Ogni singolo elemento è semplice. Se ci si concentra solo sull'elemento <a>
, viene visualizzato questo markup:
<a href="~/EditMovie?id=@item.ID)">Edit</a>
Informazioni generali sul funzionamento della griglia: la griglia visualizza le righe, una per ogni record di database e visualizza le colonne per ogni campo nel record del database. Durante la costruzione di ogni riga della griglia, l'oggetto item
contiene il record di database (elemento) per tale riga. Questa disposizione consente di ottenere nel codice i dati per tale riga. Ecco cosa viene visualizzato qui: l'espressione item.ID
ottiene il valore ID dell'elemento di database corrente. È possibile ottenere uno qualsiasi dei valori del database (titolo, genere o anno) allo stesso modo usando item.Title
, item.Genre
o item.Year
.
L'espressione "~/EditMovie?id=@item.ID
combina la parte hardcoded dell'URL di destinazione (~/EditMovie?id=
) con questo ID derivato in modo dinamico. L'operatore ~
è stato visualizzato nell'esercitazione precedente. Si tratta di un operatore ASP.NET che rappresenta la radice del sito Web corrente.
Il risultato è che questa parte del markup nella colonna produce semplicemente un markup simile al markup seguente in fase di esecuzione:
href="/EditMovie?id=2"
Naturalmente, il valore effettivo di id
sarà diverso per ogni riga.
Creazione di una visualizzazione personalizzata per una colonna griglia
Tornare ora alla colonna della griglia. Le tre colonne originariamente presenti nella griglia visualizzavano solo i valori di dati (titolo, genere e anno). Questa visualizzazione è stata specificata passando il nome della colonna del database, grid.Column("Title")
ad esempio .
Questa nuova colonna di collegamento Modifica è diversa. Anziché specificare un nome di colonna, si passa un format
parametro. Questo parametro consente di definire il markup che verrà eseguito dall'helper WebGrid
insieme al item
valore per visualizzare i dati della colonna come grassetto o verde o in qualsiasi formato desiderato. Ad esempio, se si vuole che il titolo venga visualizzato in grassetto, è possibile creare una colonna come nell'esempio seguente:
grid.Column(format:@<strong>@item.Title</strong>)
I vari @
caratteri visualizzati nella format
proprietà contrassegnano la transizione tra markup e un valore di codice.
Dopo aver appreso la format
proprietà, è più facile comprendere in che modo viene creata la nuova colonna di collegamento Modifica :
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
La colonna è costituita solo dal markup che esegue il rendering del collegamento, oltre ad alcune informazioni (ID) estratte dal record di database per la riga.
Suggerimento
Parametri denominati e parametri posizionali per un metodo
Molte volte, quando è stato chiamato un metodo e sono stati passati parametri, è sufficiente elencare i valori dei parametri separati da virgole. Ecco alcuni esempi:
db.Execute(insertCommand, title, genre, year)
Validation.RequireField("title", "You must enter a title")
Non è stato menzionato il problema quando è stato visualizzato per la prima volta questo codice, ma in ogni caso si passano parametri ai metodi in un ordine specifico, ovvero l'ordine in cui i parametri sono definiti in tale metodo. Per db.Execute
e Validation.RequireFields
, se si mescola l'ordine dei valori passati, viene visualizzato un messaggio di errore quando viene eseguita la pagina o almeno alcuni risultati strani. Chiaramente, è necessario conoscere l'ordine in cui passare i parametri. In WebMatrix, IntelliSense consente di comprendere il nome, il tipo e l'ordine dei parametri.
In alternativa al passaggio di valori in ordine, è possibile usare parametri denominati. Il passaggio dei parametri in ordine è noto come uso di parametri posizionali. Per i parametri denominati, si include in modo esplicito il nome del parametro quando si passa il relativo valore. In queste esercitazioni sono già stati usati parametri denominati. Ad esempio:
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3)
e
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year")
)
)
I parametri denominati sono utili per un paio di situazioni, soprattutto quando un metodo accetta molti parametri. Uno è quando si desidera passare solo uno o due parametri, ma i valori che si desidera passare non sono tra le prime posizioni nell'elenco di parametri. Un'altra situazione è quando si vuole rendere il codice più leggibile passando i parametri nell'ordine più appropriato.
Ovviamente, per usare parametri denominati, è necessario conoscere i nomi dei parametri. WebMatrix IntelliSense può visualizzare i nomi, ma attualmente non può compilarli automaticamente.
Creazione della pagina di modifica
È ora possibile creare la pagina EditMovie . Quando gli utenti fanno clic sul collegamento Modifica , verranno visualizzati in questa pagina.
Creare una pagina denominata EditMovie.cshtml e sostituire il contenuto del file con il markup seguente:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit a Movie</title>
<style>
.validation-summary-errors{
border:2px dashed red;
color:red;
font-weight:bold;
margin:12px;
}
</style>
</head>
<body>
<h1>Edit 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="@title" /></p>
<p><label for="genre">Genre:</label>
<input type="text" name="genre" value="@genre" /></p>
<p><label for="year">Year:</label>
<input type="text" name="year" value="@year" /></p>
<input type="hidden" name="movieid" value="@movieId" />
<p><input type="submit" name="buttonSubmit" value="Submit Changes" /></p>
</fieldset>
</form>
</body>
</html>
Questo markup e codice è simile a quello disponibile nella pagina AddMovie . C'è una piccola differenza nel testo per il pulsante di invio. Come per la pagina AddMovie , è presente una Html.ValidationSummary
chiamata che visualizzerà gli errori di convalida, se presenti. Questa volta si esce dalle chiamate a Validation.Message
, poiché gli errori verranno visualizzati nel riepilogo della convalida. Come indicato nell'esercitazione precedente, è possibile usare il riepilogo della convalida e i singoli messaggi di errore in varie combinazioni.
Si noti di nuovo che l'attributo method
dell'elemento <form>
è impostato su post
. Come per la pagina AddMovie.cshtml , questa pagina apporta modifiche al database. Pertanto, questo modulo deve eseguire un'operazione POST
. Per altre informazioni sulla differenza tra GET
e POST
operazioni, vedere la barra laterale GET, POST e HTTP Verb Safety nell'esercitazione sui moduli HTML.
Come illustrato in un'esercitazione precedente, gli value
attributi delle caselle di testo vengono impostati con il codice Razor per precaricarli. Questa volta, tuttavia, si usano variabili come title
e genre
per l'attività invece di Request.Form["title"]
:
<input type="text" name="title" value="@title" />
Come in precedenza, questo markup preloadrà i valori della casella di testo con i valori del filmato. Si noterà in un momento perché è utile usare le variabili questa volta invece di usare l'oggetto Request
.
C'è anche un <input type="hidden">
elemento in questa pagina. Questo elemento archivia l'ID filmato senza renderlo visibile nella pagina. L'ID viene inizialmente passato alla pagina usando un valore stringa di query (?id=7
o simile nell'URL). Inserendo il valore ID in un campo nascosto, è possibile assicurarsi che sia disponibile quando il modulo viene inviato, anche se non si ha più accesso all'URL originale con cui è stata richiamata la pagina.
A differenza della pagina AddMovie , il codice per la pagina EditMovie ha due funzioni distinte. La prima funzione è che quando la pagina viene visualizzata per la prima volta (e solo quindi), il codice ottiene l'ID filmato dalla stringa di query. Il codice usa quindi l'ID per leggere il filmato corrispondente fuori dal database e visualizzarlo (preload) nelle caselle di testo.
La seconda funzione è che quando l'utente fa clic sul pulsante Invia modifiche , il codice deve leggere i valori delle caselle di testo e convalidarli. Il codice deve anche aggiornare l'elemento di database con i nuovi valori. Questa tecnica è simile all'aggiunta di un record, come si è visto in AddMovie.
Aggiunta di codice per leggere un singolo filmato
Per eseguire la prima funzione, aggiungere questo codice alla parte superiore della pagina:
@{
var title = "";
var genre = "";
var year = "";
var movieId = "";
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty()){
movieId = Request.QueryString["ID"];
var db = Database.Open("WebPagesMovies");
var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
var row = db.QuerySingle(dbCommand, movieId);
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else{
Validation.AddFormError("No movie was selected.");
}
}
}
La maggior parte di questo codice si trova all'interno di un blocco che avvia if(!IsPost)
. L'operatore !
indica "not", quindi l'espressione indica se questa richiesta non è un invio post, che è un modo indiretto di dire se questa richiesta è la prima volta che questa pagina è stata eseguita. Come indicato in precedenza, questo codice deve essere eseguito solo la prima volta che viene eseguita la pagina. Se non è stato racchiuso il codice in if(!IsPost)
, verrà eseguito ogni volta che viene richiamata la pagina, sia la prima volta che si risponde a un pulsante.
Si noti che il codice include un else
blocco questa volta. Come detto quando sono stati introdotti if
blocchi, a volte si vuole eseguire codice alternativo se la condizione di test non è vera. Questo è il caso qui. Se la condizione passa , ovvero se l'ID passato alla pagina è ok, si legge una riga dal database. Tuttavia, se la condizione non passa, il blocco viene eseguito e il else
codice imposta un messaggio di errore.
Convalida di un valore passato alla pagina
Il codice usa Request.QueryString["id"]
per ottenere l'ID passato alla pagina. Il codice assicura che un valore sia stato effettivamente passato per l'ID. Se non è stato passato alcun valore, il codice imposta un errore di convalida.
Questo codice mostra un modo diverso per convalidare le informazioni. Nell'esercitazione precedente è stato usato l'helper Validation
. I campi registrati per convalidare e ASP.NET eseguire automaticamente la convalida e visualizzare gli errori usando Html.ValidationMessage
e Html.ValidationSummary
. In questo caso, tuttavia, non si sta convalidando l'input dell'utente. Si convalida invece un valore passato alla pagina da un'altra parte. L'helper Validation
non lo fa per te.
Di conseguenza, controllare il valore autonomamente, testandolo con if(!Request.QueryString["ID"].IsEmpty()
). Se si verifica un problema, è possibile visualizzare l'errore usando Html.ValidationSummary
, come si è fatto con l'helper Validation
. A tale scopo, chiamare Validation.AddFormError
e passare un messaggio da visualizzare. Validation.AddFormError
è un metodo predefinito che consente di definire messaggi personalizzati che si collegano con il sistema di convalida già familiare. Più avanti in questa esercitazione si parlerà di come rendere il processo di convalida un po'più affidabile.
Dopo aver verificato che sia presente un ID per il film, il codice legge il database, cercando solo un singolo elemento di database. Probabilmente si è notato il modello generale per le operazioni del database: aprire il database, definire un'istruzione SQL ed eseguire l'istruzione. Questa volta, l'istruzione SQL Select
include WHERE ID = @0
. Poiché l'ID è univoco, è possibile restituire un solo record.
La query viene eseguita usando db.QuerySingle
(non db.Query
, come usato per l'elenco di film) e il codice inserisce il risultato nella row
variabile. Il nome è arbitrario. È possibile assegnare un nome row
alle variabili che si desidera. Le variabili inizializzate nella parte superiore vengono quindi riempite con i dettagli del film in modo che questi valori possano essere visualizzati nelle caselle di testo.
Test della pagina di modifica (finora)
Se si vuole testare la pagina, eseguire la pagina Film ora e fare clic su un collegamento Modifica accanto a qualsiasi filmato. Verrà visualizzata la pagina EditMovie con i dettagli compilati per il film selezionato:
Si noti che l'URL della pagina include qualcosa come ?id=10
(o un altro numero). Finora è stato testato che Modificare i collegamenti nella pagina Film funziona, che la pagina legge l'ID dalla stringa di query e che la query di database per ottenere un singolo record di film funziona.
È possibile modificare le informazioni del film, ma non accade nulla quando si fa clic su Invia modifiche.
Aggiunta di codice per aggiornare il filmato con le modifiche dell'utente
Nel file EditMovie.cshtml per implementare la seconda funzione (salvataggio delle modifiche), aggiungere il codice seguente solo all'interno della parentesi graffe di chiusura del @
blocco. Se non si è certi esattamente dove inserire il codice, è possibile esaminare l'elenco di codice completo per la pagina Modifica film visualizzata alla fine di questa esercitazione.
if(IsPost){
Validation.RequireField("title", "You must enter a title");
Validation.RequireField("genre", "Genre is required");
Validation.RequireField("year", "You haven't entered a year");
Validation.RequireField("movieid", "No movie ID was submitted!");
title = Request.Form["title"];
genre = Request.Form["genre"];
year = Request.Form["year"];
movieId = Request.Form["movieId"];
if(Validation.IsValid()){
var db = Database.Open("WebPagesMovies");
var updateCommand = "UPDATE Movies SET Title=@0, Genre=@1, Year=@2 WHERE Id=@3";
db.Execute(updateCommand, title, genre, year, movieId);
Response.Redirect("~/Movies");
}
}
Anche in questo caso, questo markup e codice è simile al codice in AddMovie. Il codice si trova in un if(IsPost)
blocco, perché questo codice viene eseguito solo quando l'utente fa clic sul pulsante Invia modifiche , ovvero quando (e solo quando) il modulo è stato pubblicato. In questo caso, non si usa un test simile if(IsPost && Validation.IsValid())
, ovvero non si combinano entrambi i test usando AND. In questa pagina viene innanzitutto determinato se è presente un invio di modulo (if(IsPost)
) e quindi registrare i campi per la convalida. È quindi possibile testare i risultati della convalida (if(Validation.IsValid()
). Il flusso è leggermente diverso rispetto alla pagina AddMovie.cshtml , ma l'effetto è lo stesso.
Si ottengono i valori delle caselle di testo usando Request.Form["title"]
e codice simile per gli altri <input>
elementi. Si noti che questa volta, il codice ottiene l'ID filmato dal campo nascosto (<input type="hidden">
). Quando la pagina è stata eseguita la prima volta, il codice ha ottenuto l'ID dalla stringa di query. Si ottiene il valore dal campo nascosto per assicurarsi di ottenere l'ID del film che è stato originariamente visualizzato, nel caso in cui la stringa di query sia stata in qualche modo modificata da allora.
La differenza davvero importante tra il codice AddMovie e questo codice è che in questo codice si usa l'istruzione SQL Update
anziché l'istruzione Insert Into
. Nell'esempio seguente viene illustrata la sintassi dell'istruzione SQL Update
:
UPDATE table SET col1="value", col2="value", col3="value" ... WHERE ID = value
È possibile specificare qualsiasi colonna in qualsiasi ordine e non è necessariamente necessario aggiornare ogni colonna durante un'operazione Update
. Non è possibile aggiornare l'ID stesso, perché ciò potrebbe salvare il record come nuovo record e non è consentito per un'operazione Update
.
Nota
Importante La Where
clausola con l'ID è molto importante, perché questo è il modo in cui il database conosce il record del database che si vuole aggiornare. Se è stata interrotta la Where
clausola, il database aggiornerebbe ogni record nel database. Nella maggior parte dei casi, si tratta di un disastro.
Nel codice i valori da aggiornare vengono passati all'istruzione SQL usando i segnaposto. Per ripetere ciò che è stato detto prima: per motivi di sicurezza, usare solo i segnaposto per passare i valori a un'istruzione SQL.
Dopo aver usato db.Execute
il codice per eseguire l'istruzione Update
, viene reindirizzato alla pagina di presentazione, in cui è possibile visualizzare le modifiche.
Suggerimento
Istruzioni SQL diverse, diversi metodi
Potrebbe essere stato notato che si usano metodi leggermente diversi per eseguire istruzioni SQL diverse. Per eseguire una Select
query che restituisce potenzialmente più record, usare il Query
metodo . Per eseguire una Select
query che si conosce restituirà un solo elemento di database, usare il QuerySingle
metodo . Per eseguire comandi che apportano modifiche, ma che non restituiscono elementi di database, si usa il Execute
metodo .
È necessario disporre di metodi diversi perché ognuno di essi restituisce risultati diversi, come si è già visto nella differenza tra Query
e QuerySingle
. Il Execute
metodo restituisce effettivamente anche un valore, ovvero il numero di righe di database interessate dal comando, ma è stato ignorato finora.
Naturalmente, il Query
metodo potrebbe restituire una sola riga di database. Tuttavia, ASP.NET considera sempre i risultati del Query
metodo come raccolta. Anche se il metodo restituisce una sola riga, è necessario estrarre tale singola riga dalla raccolta. Pertanto, in situazioni in cui si sa che si tornerà a una sola riga, è un po 'più pratico usare QuerySingle
.
Esistono alcuni altri metodi che eseguono tipi specifici di operazioni di database. È possibile trovare un elenco di metodi di database nel Pagine Web ASP.NET Riferimento rapido all'API.
Creazione della convalida per l'ID più affidabile
La prima volta che viene eseguita la pagina, viene ottenuto l'ID filmato dalla stringa di query in modo che sia possibile ottenere tale filmato dal database. È stato verificato che in realtà fosse presente un valore da cercare, che è stato eseguito usando questo codice:
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty()){
// Etc.
}
}
Questo codice è stato usato per assicurarsi che se un utente si trova nella pagina EditMovies senza prima selezionare un film nella pagina Film , la pagina visualizzerà un messaggio di errore descrittivo. In caso contrario, gli utenti visualizzerebbero un errore che probabilmente li confonderebbe.
Tuttavia, questa convalida non è molto affidabile. La pagina potrebbe anche essere richiamata con questi errori:
- L'ID non è un numero. Ad esempio, la pagina potrebbe essere richiamata con un URL come
http://localhost:nnnnn/EditMovie?id=abc
. - L'ID è un numero, ma fa riferimento a un film che non esiste , ad esempio
http://localhost:nnnnn/EditMovie?id=100934
.
Se si è curiosi di visualizzare gli errori risultanti da questi URL, eseguire la pagina Film . Selezionare un filmato da modificare e quindi modificare l'URL della pagina EditMovie in un URL contenente un ID alfabetico o l'ID di un film non esistente.
Quindi cosa dovresti fare? La prima correzione consiste nel assicurarsi che non solo sia un ID passato alla pagina, ma che l'ID sia un intero. Modificare il codice per il test in modo che sia simile all'esempio !IsPost
seguente:
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
// Etc.
È stata aggiunta una seconda condizione al IsEmpty
test, collegata con &&
(logico AND):
Request.QueryString["ID"].IsInt()
È possibile ricordare dall'esercitazione Introduzione a Pagine Web ASP.NET programmazione che metodi come AsBool
una AsInt
stringa di caratteri vengono convertiti in un altro tipo di dati. Il IsInt
metodo (e altri, come IsBool
e IsDateTime
) sono simili. Tuttavia, provano solo se è possibile convertire la stringa, senza eseguire effettivamente la conversione. Quindi, qui si dice essenzialmente se il valore della stringa di query può essere convertito in un intero ....
L'altro potenziale problema sta cercando un film che non esiste. Il codice per ottenere un filmato è simile al codice seguente:
var row = db.QuerySingle(dbCommand, movieId);
Se si passa un movieId
valore al metodo che non corrisponde a QuerySingle
un filmato effettivo, non viene restituito alcun valore e le istruzioni che seguono (ad esempio, title=row.Title
) generano errori.
Di nuovo c'è una soluzione semplice. Se il metodo non restituisce risultati, la db.QuerySingle
row
variabile sarà Null. È quindi possibile verificare se la row
variabile è Null prima di provare a ottenere valori da esso. Il codice seguente aggiunge un if
blocco intorno alle istruzioni che ottengono i valori dall'oggetto row
:
if(row != null) {
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else{
Validation.AddFormError("No movie was found for that ID.");
}
Con questi due test di convalida aggiuntivi, la pagina diventa più puntata. Il codice completo per il ramo è ora simile al !IsPost
seguente:
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
movieId = Request.QueryString["ID"];
var db = Database.Open("WebPagesMovies");
var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
var row = db.QuerySingle(dbCommand, movieId);
if(row != null) {
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else {
Validation.AddFormError("No movie was found for that ID.");
}
}
else {
Validation.AddFormError("No movie was selected.");
}
}
Si noti una volta di più che questa attività è un buon uso per un else
blocco. Se i test non superano, i else
blocchi impostano i messaggi di errore.
Aggiunta di un collegamento per tornare alla pagina Film
Un dettaglio finale e utile consiste nell'aggiungere un collegamento alla pagina Film . Nel flusso ordinario di eventi, gli utenti inizieranno nella pagina Film e fare clic su un collegamento Modifica . Ciò li porta alla pagina EditMovie , in cui possono modificare il film e fare clic sul pulsante. Dopo aver elaborato la modifica, il codice viene reindirizzato alla pagina Film .
Tuttavia:
- L'utente potrebbe decidere di non modificare nulla.
- L'utente potrebbe aver ottenuto in questa pagina senza prima fare clic su un collegamento Modifica nella pagina Film .
In entrambi i casi, si vuole semplificare per loro di tornare all'elenco principale. È una correzione semplice: aggiungere il markup seguente subito dopo il tag di chiusura </form>
nel markup:
<p><a href="~/Movies">Return to movie listing</a></p>
Questo markup usa la stessa sintassi per un <a>
elemento visualizzato altrove. L'URL include ~
la "radice del sito Web".
Test del processo di aggiornamento del film
È ora possibile testare. Eseguire la pagina Film e fare clic su Modifica accanto a un filmato. Quando viene visualizzata la pagina EditMovie , apportare modifiche al film e fare clic su Invia modifiche. Quando viene visualizzata la presentazione del film, assicurarsi che vengano visualizzate le modifiche.
Per assicurarsi che la convalida funzioni, fare clic su Modifica per un altro film. Quando si passa alla pagina EditMovie , deselezionare il campo Genere (o Anno o entrambi) e provare a inviare le modifiche. Verrà visualizzato un errore, come si prevede:
Fare clic sul collegamento Ritorno al film per abbandonare le modifiche e tornare alla pagina Film .
Prossima ora
Nell'esercitazione successiva si vedrà come eliminare un record di film.
Pagina completa elenco per film (aggiornata con modifica collegamenti)
@{
var db = Database.Open("WebPagesMovies") ;
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
searchTerm = Request.QueryString["searchGenre"];
}
if(!Request.QueryString["searchTitle"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
searchTerm = "%" + Request.QueryString["searchTitle"] + "%";
}
var selectedData = db.Query(selectCommand, searchTerm);
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Movies</title>
<style type="text/css">
.grid { margin: 4px; border-collapse: collapse; width: 600px; }
.grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
.head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
.alt { background-color: #E8E8E8; color: #000; }
</style>
</head>
<body>
<h1>Movies</h1>
<form method="get">
<div>
<label for="searchGenre">Genre to look for:</label>
<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
<input type="Submit" value="Search Genre" /><br/>
(Leave blank to list all movies.)<br/>
</div>
<div>
<label for="SearchTitle">Movie title contains the following:</label>
<input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
<input type="Submit" value="Search Title" /><br/>
</div>
</form>
<div>
@grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column(format: @<a href="~/EditMovie?id=@item.ID">Edit</a>),
grid.Column("Title"),
grid.Column("Genre"),
grid.Column("Year")
)
)
</div>
<p>
<a href="~/AddMovie">Add a movie</a>
</p>
</body>
</html>
Elenco pagina completa per la pagina Modifica film
@{
var title = "";
var genre = "";
var year = "";
var movieId = "";
if(!IsPost){
if(!Request.QueryString["ID"].IsEmpty() && Request.QueryString["ID"].IsInt()) {
movieId = Request.QueryString["ID"];
var db = Database.Open("WebPagesMovies");
var dbCommand = "SELECT * FROM Movies WHERE ID = @0";
var row = db.QuerySingle(dbCommand, movieId);
if(row != null) {
title = row.Title;
genre = row.Genre;
year = row.Year;
}
else{
Validation.AddFormError("No movie was selected.");
}
}
else{
Validation.AddFormError("No movie was selected.");
}
}
if(IsPost){
Validation.RequireField("title", "You must enter a title");
Validation.RequireField("genre", "Genre is required");
Validation.RequireField("year", "You haven't entered a year");
Validation.RequireField("movieid", "No movie ID was submitted!");
title = Request.Form["title"];
genre = Request.Form["genre"];
year = Request.Form["year"];
movieId = Request.Form["movieId"];
if(Validation.IsValid()){
var db = Database.Open("WebPagesMovies");
var updateCommand = "UPDATE Movies SET Title=@0, Genre=@1, Year=@2 WHERE Id=@3";
db.Execute(updateCommand, title, genre, year, movieId);
Response.Redirect("~/Movies");
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit a Movie</title>
<style>
.validation-summary-errors{
border:2px dashed red;
color:red;
font-weight:bold;
margin:12px;
}
</style>
</head>
<body>
<h1>Edit 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="@title" /></p>
<p><label for="genre">Genre:</label>
<input type="text" name="genre" value="@genre" /></p>
<p><label for="year">Year:</label>
<input type="text" name="year" value="@year" /></p>
<input type="hidden" name="movieid" value="@movieId" />
<p><input type="submit" name="buttonSubmit" value="Submit Changes" /></p>
</fieldset>
</form>
<p><a href="~/Movies">Return to movie listing</a></p>
</body>
</html>