Introduzione a Pagine Web ASP.NET - Nozioni di base sul modulo HTML
Questa esercitazione illustra le nozioni di base su come creare un modulo di input e come gestire l'input dell'utente quando si usa Pagine Web ASP.NET (Razor). Ora che si dispone di un database, si useranno le competenze del modulo per consentire agli utenti di trovare film specifici nel database. Si presuppone che la serie sia stata completata tramite Introduzione alla visualizzazione dei dati usando Pagine Web ASP.NET.
Contenuto dell'esercitazione:
- Come creare un modulo usando elementi HTML standard.
- Come leggere l'input dell'utente in un modulo.
- Come creare una query SQL che ottiene in modo selettivo i dati usando un termine di ricerca fornito dall'utente.
- Come avere campi nella pagina "ricorda" cosa ha immesso l'utente.
Funzionalità/tecnologie illustrate:
- Oggetto
Request
.- Clausola SQL
Where
.
Scopo dell'esercitazione
Nell'esercitazione precedente è stato creato un database, sono stati aggiunti dati e quindi è stato usato l'helper WebGrid
per visualizzare i dati. In questa esercitazione si aggiungerà una casella di ricerca che consente di trovare film di un genere specifico o il cui titolo contiene qualsiasi parola immessa. Ad esempio, sarà possibile trovare tutti i film il cui genere è "Azione" o il cui titolo contiene "Harry" o "Adventure".
Al termine dell'esercitazione, si avrà una pagina simile a quella seguente:
La parte dell'elenco della pagina è uguale all'ultima esercitazione: una griglia. La differenza sarà che la griglia mostrerà solo i film che hai cercato.
Informazioni sui moduli HTML
Se si ha esperienza con la creazione di moduli HTML e con la differenza tra GET
e POST
, è possibile ignorare questa sezione.
Un modulo include elementi di input utente: caselle di testo, pulsanti, pulsanti di opzione, caselle di controllo, elenchi a discesa e così via. Gli utenti compilano questi controlli o effettuano selezioni e quindi invia il modulo facendo clic su un pulsante.
La sintassi HTML di base di un modulo è illustrata in questo esempio:
<form method="post">
<input type="text" name="name" value="" />
<br/>
<input type="submit" name="submit" value="Submit" />
</form>
Quando questo markup viene eseguito in una pagina, crea un modulo semplice simile alla figura seguente:
L'elemento <form>
racchiude elementi HTML da inviare. Un semplice errore da fare consiste nell'aggiungere elementi alla pagina, ma dimenticare di inserirli all'interno di un <form>
elemento. In tal caso, non viene inviato nulla. L'attributo method
indica al browser come inviare l'input dell'utente. Questa opzione post
viene impostata su se si esegue un aggiornamento nel server o get
su se si recuperano solo i dati dal server.
Suggerimento
Sicurezza dei verbi GET, POST e HTTP
HTTP, il protocollo usato dai browser e dai server per scambiare informazioni, è notevolmente semplice nelle sue operazioni di base. I browser usano solo alcuni verbi per effettuare richieste ai server. Quando si scrive codice per il Web, è utile comprendere questi verbi e come il browser e il server li usano. Lontano e lontano i verbi più comunemente usati sono questi:
GET
. Il browser usa questo verbo per recuperare qualcosa dal server. Ad esempio, quando si digita un URL nel browser, il browser esegue un'operazioneGET
per richiedere la pagina desiderata. Se la pagina include grafica, il browser esegue operazioni aggiuntiveGET
per ottenere le immagini. Se l'operazioneGET
deve passare informazioni al server, le informazioni vengono passate come parte dell'URL nella stringa di query.POST
. Il browser invia unaPOST
richiesta per inviare dati da aggiungere o modificare nel server. Ad esempio, ilPOST
verbo viene usato per creare record in un database o modificare quelli esistenti. La maggior parte del tempo, quando si compila un modulo e si fa clic sul pulsante invia, il browser esegue un'operazionePOST
. In un'operazionePOST
, i dati passati al server si trovano nel corpo della pagina.
Una distinzione importante tra questi verbi è che un'operazione GET
non dovrebbe cambiare nulla nel server , o per inserirla in modo leggermente più astratta, un'operazione GET
non comporta una modifica nello stato del server. È possibile eseguire un'operazione GET
sulle stesse risorse quante più volte desiderate e queste risorse non cambiano. Un'operazione GET
viene spesso detta "sicura" o per usare un termine tecnico, è idempotente. Al contrario, una POST
richiesta cambia qualcosa nel server ogni volta che si esegue l'operazione.
Due esempi consentono di illustrare questa distinzione. Quando si esegue una ricerca usando un motore come Bing o Google, si compila un modulo costituito da una casella di testo e quindi si fa clic sul pulsante di ricerca. Il browser esegue un'operazione GET
, con il valore immesso nella casella passata come parte dell'URL. L'uso di un'operazione per questo tipo di modulo è corretto, perché un'operazione GET
di ricerca non modifica le risorse nel server, recupera solo informazioni.
Ora prendere in considerazione il processo di ordinamento di qualcosa online. Si compilano i dettagli dell'ordine e quindi si fa clic sul pulsante invia. Questa operazione sarà una POST
richiesta, perché l'operazione comporterà modifiche nel server, ad esempio un nuovo record di ordine, una modifica delle informazioni sull'account e forse molte altre modifiche. A differenza dell'operazione, non è possibile ripetere la GET
POST
richiesta, se è stata eseguita, ogni volta che la richiesta è stata rimessa, si genererà un nuovo ordine nel server. In casi come questo, i siti Web spesso avvisano di non fare clic su un pulsante di invio più volte o disabilitare il pulsante di invio in modo da non inviare accidentalmente il modulo.
Nel corso di questa esercitazione si userà sia un'operazione che un'operazione GET
POST
per usare i moduli HTML. Verrà spiegato in ogni caso perché il verbo usato è quello appropriato.
Per altre informazioni sui verbi HTTP, vedere l'articolo Definizioni dei metodi nel sito W3C.
La maggior parte degli elementi di input utente sono elementi HTML <input>
. Sono simili <input type="type" name="name">,
a dove tipo indica il tipo di controllo di input utente desiderato. Questi elementi sono quelli comuni:
- Casella di testo:
<input type="text">
- Casella di controllo:
<input type="check">
- Pulsante di opzione:
<input type="radio">
- Pulsante:
<input type="button">
- Pulsante Invia:
<input type="submit">
È anche possibile usare l'elemento per creare una casella di testo multilinea e l'elemento <textarea>
<select>
per creare un elenco a discesa o un elenco scorrevole. Per altre informazioni sugli elementi del modulo HTML, vedere Moduli HTML e Input nel sito W3Schools.
L'attributo name
è molto importante, perché il nome è il modo in cui si otterrà il valore dell'elemento in un secondo momento, come si vedrà brevemente.
La parte interessante è ciò che si fa, lo sviluppatore di pagine, con l'input dell'utente. Non esiste alcun comportamento predefinito associato a questi elementi. È invece necessario ottenere i valori immessi o selezionati dall'utente e eseguire operazioni con loro. Ecco cosa si apprenderà in questa esercitazione.
Suggerimento
Html5 e moduli di input
Come si potrebbe sapere, HTML è in transizione e la versione più recente (HTML5) include il supporto per modi più intuitivi per gli utenti di immettere informazioni. Ad esempio, in HTML5, l'utente (sviluppatore di pagine) può indicare alla pagina che si vuole che l'utente immetti una data. Il browser può quindi visualizzare automaticamente un calendario anziché richiedere all'utente di immettere manualmente una data. Tuttavia, HTML5 è nuovo e non è ancora supportato in tutti i browser.
Pagine Web ASP.NET supporta l'input HTML5 nella misura in cui il browser dell'utente esegue. Per un'idea dei nuovi attributi per l'elemento <input>
in HTML5, vedere Attributo del tipo di input> HTML < nel sito W3Schools.
Creazione del form
Nell'area di lavoro File di WebMatrix aprire la pagina Movies.cshtml .
Dopo il tag di chiusura </h1>
e prima del tag di apertura <div>
della grid.GetHtml
chiamata, aggiungere il markup seguente:
<form method="get">
<div>
<label for="searchGenre">Genre to look for:</label>
<input type="text" name="searchGenre" value="" />
<input type="Submit" value="Search Genre" /><br/>
(Leave blank to list all movies.)<br/>
</div>
</form>
Questo markup crea un modulo con una casella di testo denominata searchGenre
e un pulsante di invio. La casella di testo e il pulsante invia sono racchiusi in un <form>
elemento il cui method
attributo è impostato su get
. Tenere presente che se non si inserisce la casella di testo e si invia il pulsante all'interno di un <form>
elemento, non verrà inviato nulla quando si fa clic sul pulsante. È possibile usare il GET
verbo qui perché si sta creando un modulo che non apporta modifiche al server, ma genera solo una ricerca. Nell'esercitazione precedente è stato usato un post
metodo, ovvero come inviare modifiche al server. Si noterà che nell'esercitazione successiva.
Eseguire la pagina. Anche se non è stato definito alcun comportamento per il modulo, è possibile visualizzare l'aspetto seguente:
Immettere un valore nella casella di testo, ad esempio "Comedy". Fare quindi clic su Cerca genere.
Prendere nota dell'URL della pagina. Poiché l'attributo dell'elemento method
viene impostato <form>
su get
, il valore immesso fa ora parte della stringa di query nell'URL, come illustrato di seguito:
http://localhost:45661/Movies.cshtml?searchGenre=Comedy
Lettura dei valori del modulo
La pagina contiene già codice che ottiene i dati del database e visualizza i risultati in una griglia. È ora necessario aggiungere codice che legge il valore della casella di testo in modo da poter eseguire una query SQL che includa il termine di ricerca.
Poiché si imposta il metodo del modulo su get
, è possibile leggere il valore immesso nella casella di testo usando codice simile al seguente:
var searchTerm = Request.QueryString["searchGenre"];
L'oggetto (la QueryString
proprietà dell'oggettoRequest
) include i valori degli elementi inviati come parte dell'operazioneGET
.Request.QueryString
La Request.QueryString
proprietà contiene una raccolta (un elenco) dei valori inviati nel modulo. Per ottenere qualsiasi singolo valore, specificare il nome dell'elemento desiderato. Ecco perché è necessario avere un name
attributo sull'elemento <input>
(searchTerm
) che crea la casella di testo. Per altre informazioni sull'oggetto Request
, vedere la barra laterale più avanti.
È abbastanza semplice leggere il valore della casella di testo. Tuttavia, se l'utente non ha immesso nulla nella casella di testo ma ha fatto clic su Cerca comunque, è possibile ignorare tale clic, poiché non c'è nulla da cercare.
Il codice seguente è un esempio che illustra come implementare queste condizioni. Non è ancora necessario aggiungere questo codice. Questa operazione verrà eseguita in un momento.
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
// Do something here
}
Il test si suddivide in questo modo:
- Ottenere il valore di
Request.QueryString["searchGenre"]
, ovvero il valore immesso nell'elemento<input>
denominatosearchGenre
. - Verificare se è vuoto usando il
IsEmpty
metodo . Questo metodo è il modo standard per determinare se un elemento (ad esempio, un elemento modulo) contiene un valore. Ma davvero, ti interessa solo se non è vuoto, quindi ... - Aggiungere l'operatore
!
davanti alIsEmpty
test. L'operatore!
indica NOT logico.
In inglese normale, l'intera if
condizione si traduce nel seguente: se l'elemento searchGenre del modulo non è vuoto, allora ...
Questo blocco imposta la fase per la creazione di una query che usa il termine di ricerca. Questa operazione viene illustrata nella sezione seguente.
Suggerimento
Oggetto Request
L'oggetto Request
contiene tutte le informazioni inviate dal browser all'applicazione quando viene richiesta o inviata una pagina. Questo oggetto include tutte le informazioni fornite dall'utente, ad esempio i valori della casella di testo o un file da caricare. Include anche tutti i tipi di informazioni aggiuntive, ad esempio cookie, valori nella stringa di query URL (se presente), il percorso del file della pagina in esecuzione, il tipo di browser usato dall'utente, l'elenco di lingue impostate nel browser e molto altro ancora.
L'oggetto Request
è una raccolta (elenco) di valori. Per ottenere un singolo valore dalla raccolta, specificarne il nome:
var someValue = Request["name"];
L'oggetto Request
espone effettivamente diversi subset. Ad esempio:
Request.Form
fornisce i valori degli elementi all'interno dell'elemento inviato<form>
se la richiesta è unaPOST
richiesta.Request.QueryString
fornisce solo i valori nella stringa di query dell'URL. In un URL comehttp://mysite/myapp/page?searchGenre=action&page=2
, la?searchGenre=action&page=2
sezione dell'URL è la stringa di query.Request.Cookies
la raccolta consente di accedere ai cookie inviati dal browser.
Per ottenere un valore noto che si trova nel modulo inviato, è possibile usare Request["name"]
. In alternativa, è possibile usare le versioni Request.Form["name"]
più specifiche (per POST
le richieste) o Request.QueryString["name"]
(per GET
le richieste). Naturalmente, il nome è il nome dell'elemento da ottenere.
Il nome dell'elemento da ottenere deve essere univoco all'interno della raccolta in uso. Ecco perché l'oggetto Request
fornisce i subset come Request.Form
e Request.QueryString
. Si supponga che la pagina contenga un elemento modulo denominato userName
e contenga anche un cookie denominato userName
. Se si ottiene Request["userName"]
, è ambiguo se si desidera che il valore del modulo o il cookie. Tuttavia, se si ottiene Request.Form["userName"]
o Request.Cookie["userName"]
, si è espliciti su quale valore ottenere.
È consigliabile essere specifici e usare il subset di Request
cui si è interessati, ad esempio Request.Form
o Request.QueryString
. Per le pagine semplici create in questa esercitazione, probabilmente non fa alcuna differenza. Tuttavia, quando si creano pagine più complesse, usando la versione Request.Form
esplicita o Request.QueryString
è possibile evitare problemi che possono verificarsi quando la pagina contiene un modulo (o più moduli), cookie, valori di stringa di query e così via.
Creazione di una query tramite un termine di ricerca
Dopo aver appreso come ottenere il termine di ricerca immesso dall'utente, è possibile creare una query che lo usa. Tenere presente che per ottenere tutti gli elementi del film dal database, si usa una query SQL simile a questa istruzione:
SELECT * FROM Movies
Per ottenere solo determinati film, è necessario usare una query che include una Where
clausola . Questa clausola consente di impostare una condizione in cui le righe vengono restituite dalla query. Ecco un esempio:
SELECT * FROM Movies WHERE Genre = 'Action'
Il formato di base è WHERE column = value
. È possibile usare operatori diversi oltre =
a , ad >
esempio (maggiore di), <
(minore di), (diverso da), <=
<>
(minore o uguale a), ecc., a seconda di ciò che si sta cercando.
Se ci si chiede, le istruzioni SQL non fanno distinzione tra maiuscole e minuscole, SELECT
è uguale Select
a (o anche select
). Tuttavia, spesso le parole chiave vengono maiuscole in maiuscolo in un'istruzione SQL, ad SELECT
esempio e WHERE
, per semplificare la lettura.
Passaggio del termine di ricerca come parametro
La ricerca di un genere specifico è abbastanza semplice (WHERE Genre = 'Action'
), ma si vuole essere in grado di cercare qualsiasi genere immesso dall'utente. A tale scopo, si crea come query SQL che include un segnaposto per il valore da cercare. Sarà simile al comando seguente:
SELECT * FROM Movies WHERE Genre = @0
Il segnaposto è il @
carattere seguito da zero. Come si può intuire, una query può contenere più segnaposto, che verranno denominate @0
, @1
, @2
e così via.
Per configurare la query e passarlo effettivamente al valore, usare il codice simile al seguente:
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
selectedData = db.Query(selectCommand, Request.QueryString["searchGenre"]);
Questo codice è simile a quello già fatto per visualizzare i dati nella griglia. Le uniche differenze sono:
- La query contiene un segnaposto (
WHERE Genre = @0"
). - La query viene inserita in una variabile (
selectCommand
); prima è stata passata la query direttamente aldb.Query
metodo . - Quando si chiama il
db.Query
metodo , passare sia la query che il valore da usare per il segnaposto. Se la query include più segnaposto, è necessario passarle tutte come valori separati al metodo .
Se si mettono insieme tutti questi elementi, si ottiene il codice seguente:
if(!Request.QueryString["searchGenre"].IsEmpty() ) {
searchTerm = Request.QueryString["searchGenre"];
selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
selectedData = db.Query(selectCommand, searchTerm);
}
Nota
Importante! L'uso di segnaposto (ad esempio @0
) per passare valori a un comando SQL è estremamente importante per la sicurezza. Il modo in cui viene visualizzato qui, con segnaposto per i dati delle variabili, è l'unico modo per costruire comandi SQL.
Non costruire mai un'istruzione SQL mettendo insieme (concatenando) testo letterale e valori che si ottengono dall'utente. La concatenazione dell'input dell'utente in un'istruzione SQL apre il sito a un attacco SQL injection in cui un utente malintenzionato invia valori alla pagina che violano il database. Per altre informazioni, vedere l'articolo SQL Injection del sito Web MSDN.
Aggiornamento della pagina Film con il codice di ricerca
È ora possibile aggiornare il codice nel file Movies.cshtml . Per iniziare, sostituire il codice nel blocco di codice nella parte superiore della pagina con questo codice:
var db = Database.Open("WebPagesMovies");
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";
La differenza è che la query è stata inserita nella selectCommand
variabile , che verrà passata in db.Query
un secondo momento. L'inserimento dell'istruzione SQL in una variabile consente di modificare l'istruzione , operazione che verrà eseguita per eseguire la ricerca.
Queste due righe sono state rimosse anche in seguito:
var selectedData = db.Query("SELECT * FROM Movies");
var grid = new WebGrid(source: selectedData, rowsPerPage: 3);
Non si vuole ancora eseguire la query ( ovvero chiamare db.Query
) e non si vuole inizializzare ancora l'helper WebGrid
. Queste operazioni verranno eseguite dopo aver capito quale istruzione SQL deve essere eseguita.
Dopo aver riscritto questo blocco, è possibile aggiungere la nuova logica per la gestione della ricerca. Il codice completato sarà simile al seguente. Aggiornare il codice nella pagina in modo che corrisponda a questo esempio:
@{
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"];
}
var selectedData = db.Query(selectCommand, searchTerm);
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
La pagina ora funziona così. Ogni volta che viene eseguita la pagina, il codice apre il database e la selectCommand
variabile viene impostata sull'istruzione SQL che ottiene tutti i record dalla Movies
tabella. Il codice inizializza anche la searchTerm
variabile.
Tuttavia, se la richiesta corrente include un valore per l'elemento searchGenre
, il codice imposta selectCommand
su una query diversa, vale a dire a uno che include la Where
clausola per la ricerca di un genere. Imposta anche searchTerm
su qualsiasi elemento passato per la casella di ricerca (che potrebbe non essere nulla).
Indipendentemente dall'istruzione SQL in selectCommand
, il codice chiama db.Query
quindi per eseguire la query, passandolo in qualsiasi elemento in searchTerm
. Se non c'è nulla in searchTerm
, non è importante, perché in questo caso non esiste alcun parametro per passare comunque il valore a selectCommand
.
Infine, il codice inizializza l'helper WebGrid
usando i risultati della query, proprio come in precedenza.
È possibile notare che inserendo l'istruzione SQL e il termine di ricerca in variabili, è stata aggiunta la flessibilità al codice. Come si vedrà più avanti in questa esercitazione, è possibile usare questo framework di base e continuare ad aggiungere logica per diversi tipi di ricerche.
Test della funzionalità Search-by-Genre
In WebMatrix eseguire la pagina Movies.cshtml . Viene visualizzata la pagina con la casella di testo relativa al genere.
Immettere un genere immesso per uno dei record di test e quindi fare clic su Cerca. Questa volta viene visualizzato un elenco dei soli film che corrispondono a quel genere:
Immettere un genere diverso e cercare di nuovo. Provare a immettere il genere usando tutte le lettere minuscole o tutte le lettere maiuscole in modo da poter vedere che la ricerca non fa distinzione tra maiuscole e minuscole.
"Memorizzazione" di ciò che l'utente ha immesso
Potresti aver notato che dopo aver immesso un genere e aver fatto clic su Cerca genere, hai visto un elenco per quel genere. Tuttavia, la casella di testo di ricerca era vuota, in altre parole, non ricordava cosa avresti immesso.
È importante comprendere perché si verifica questo comportamento. Quando si invia una pagina, il browser invia una richiesta al server Web. Quando ASP.NET ottiene la richiesta, crea una nuova istanza della pagina, esegue il codice in esso contenuto e quindi esegue nuovamente il rendering della pagina nel browser. In effetti, tuttavia, la pagina non sa che si stava solo lavorando con una versione precedente di se stessa. Tutto ciò che sa è che ha ricevuto una richiesta che contiene alcuni dati del modulo.
Ogni volta che si richiede una pagina, per la prima volta o inviandola, si riceve una nuova pagina. Il server Web non ha memoria dell'ultima richiesta. Né ASP.NET né il browser. L'unica connessione tra queste istanze separate della pagina è costituita dai dati trasmessi tra di essi. Se si invia una pagina, ad esempio, la nuova istanza della pagina può ottenere i dati del modulo inviati dall'istanza precedente. Un altro modo per passare i dati tra le pagine consiste nell'usare i cookie.
Un modo formale per descrivere questa situazione è dire che le pagine Web sono senza stato. I server Web e le pagine stesse e gli elementi nella pagina non mantengono informazioni sullo stato precedente di una pagina. Il Web è stato progettato in questo modo perché mantenere lo stato per le singole richieste esaurisce rapidamente le risorse dei server Web, che spesso gestiscono migliaia, forse anche centinaia di migliaia, di richieste al secondo.
Ecco perché la casella di testo era vuota. Dopo aver inviato la pagina, ASP.NET creato una nuova istanza della pagina ed eseguito il codice e il markup. Non c'era nulla nel codice che ha detto ASP.NET di inserire un valore nella casella di testo. Quindi ASP.NET non ha eseguito alcuna operazione e il rendering della casella di testo è stato eseguito senza un valore in esso contenuto.
C'è in realtà un modo semplice per aggirare questo problema. Il genere immesso nella casella di testo è disponibile nel codice, ovvero in Request.QueryString["searchGenre"]
.
Aggiornare il markup per la casella di testo in modo che l'attributo ottenga il relativo valore da searchTerm
, come nell'esempio value
seguente:
<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
In questa pagina è anche possibile impostare l'attributo value
sulla searchTerm
variabile, poiché tale variabile contiene anche il genere immesso. Tuttavia, l'uso dell'oggetto per impostare l'attributo Request
value
come illustrato di seguito è il modo standard per eseguire questa attività. Supponendo di voler eseguire questa operazione, in alcune situazioni potrebbe essere necessario eseguire il rendering della pagina senza valori nei campi. Tutto dipende da ciò che sta succedendo con la tua app.
Nota
Non è possibile "ricordare" il valore di una casella di testo usata per le password. Si tratta di un foro di sicurezza per consentire agli utenti di compilare un campo password usando il codice.
Eseguire di nuovo la pagina, immettere un genere e fare clic su Cerca genere. Questa volta non solo vengono visualizzati i risultati della ricerca, ma la casella di testo ricorda ciò che è stato immesso l'ultima volta:
Ricerca di qualsiasi Word nel titolo
È ora possibile cercare qualsiasi genere, ma è anche possibile cercare un titolo. È difficile ottenere un titolo esattamente quando si esegue la ricerca, quindi è possibile cercare una parola visualizzata ovunque all'interno di un titolo. A tale scopo, usare l'operatore e la LIKE
sintassi come segue:
SELECT * FROM Movies WHERE Title LIKE '%adventure%'
Questo comando ottiene tutti i film i cui titoli contengono "adventure". Quando si usa l'operatore LIKE
, si include il carattere %
jolly come parte del termine di ricerca. La ricerca LIKE 'adventure%'
significa "a partire da 'adventure'". (Tecnicamente, significa "La stringa 'adventure' seguita da qualsiasi elemento). Analogamente, il termine LIKE '%adventure'
di ricerca significa "qualsiasi elemento seguito dalla stringa 'adventure'", che è un altro modo per dire "terminando con 'adventure'".
Il termine LIKE '%adventure%'
di ricerca significa quindi "con 'adventure' ovunque nel titolo". Tecnicamente, "qualsiasi elemento nel titolo, seguito da 'adventure', seguito da qualsiasi cosa.")
All'interno dell'elemento <form>
aggiungere il markup seguente sotto il tag di chiusura </div>
per la ricerca del genere (subito prima dell'elemento di chiusura </form>
):
<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>
Il codice per gestire questa ricerca è simile al codice per la ricerca di genere, ad eccezione del fatto che è necessario assemblare la LIKE
ricerca. All'interno del blocco di codice nella parte superiore della pagina aggiungere questo if
blocco subito dopo il if
blocco per la ricerca del genere:
if(!Request.QueryString["searchTitle"].IsEmpty() ) {
selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
searchTerm = "%" + Request["searchTitle"] + "%";
}
Questo codice usa la stessa logica illustrata in precedenza, ad eccezione del fatto che la ricerca usa un LIKE
operatore e il codice inserisce "%
" prima e dopo il termine di ricerca.
Si noti che è stato facile aggiungere un'altra ricerca alla pagina. Tutto quello che dovevi fare era:
- Creare un
if
blocco testato per verificare se la casella di ricerca pertinente ha un valore. - Impostare la
selectCommand
variabile su una nuova istruzione SQL. - Impostare la
searchTerm
variabile sul valore da passare alla query.
Ecco il blocco di codice completo, che contiene la nuova logica per una ricerca del titolo:
@{
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["searchTitle"] + "%";
}
var selectedData = db.Query(selectCommand, searchTerm);
var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:8);
}
Ecco un riepilogo delle operazioni eseguite da questo codice:
- Le variabili
searchTerm
eselectCommand
vengono inizializzate nella parte superiore. Queste variabili verranno impostate sul termine di ricerca appropriato (se presente) e sul comando SQL appropriato in base alle operazioni eseguite dall'utente nella pagina. La ricerca predefinita è il caso semplice di ottenere tutti i film dal database. - Nei test per
searchGenre
esearchTitle
il codice impostasearchTerm
il valore da cercare. Questi blocchi di codice sono impostati anche suselectCommand
un comando SQL appropriato per la ricerca. - Il
db.Query
metodo viene richiamato una sola volta, usando qualsiasi comando SQL inselectedCommand
e qualsiasi valore si trova insearchTerm
. Se non è presente alcun termine di ricerca (nessun genere e nessuna parola del titolo), il valore disearchTerm
è una stringa vuota. Tuttavia, ciò non è importante, perché in questo caso la query non richiede un parametro.
Test della funzionalità di ricerca del titolo
È ora possibile testare la pagina di ricerca completata. Eseguire Movies.cshtml.
Immettere un genere e fare clic su Cerca genere. La griglia visualizza i film di quel genere, come prima.
Immettere una parola del titolo e fare clic su Cerca titolo. Nella griglia vengono visualizzati film con tale parola nel titolo.
Lasciare vuote entrambe le caselle di testo e fare clic su uno dei due pulsanti. La griglia visualizza tutti i film.
Combinazione delle query
È possibile notare che le ricerche che è possibile eseguire sono esclusive. Non è possibile cercare il titolo e il genere contemporaneamente, anche se entrambe le caselle di ricerca contengono valori. Ad esempio, non è possibile cercare tutti i film d'azione il cui titolo contiene "Adventure". Poiché la pagina è codificata ora, se si immettono valori per genere e titolo, la ricerca del titolo ha la precedenza. Per creare una ricerca che combina le condizioni, è necessario creare una query SQL con una sintassi simile alla seguente:
SELECT * FROM Movies WHERE Genre = @0 AND Title LIKE @1
E sarebbe necessario eseguire la query usando un'istruzione simile alla seguente (approssimativamente):
var selectedData = db.Query(selectCommand, searchGenre, searchTitle);
La creazione della logica per consentire molte permutazioni dei criteri di ricerca può essere un po' coinvolta, come si può notare. Pertanto, ci fermeremo qui.
Prossima attività
Nell'esercitazione successiva si creerà una pagina che usa un modulo per consentire agli utenti di aggiungere film al database.
Elenco completo per la pagina film (aggiornata con la ricerca)
@{
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["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("Title"),
grid.Column("Genre"),
grid.Column("Year")
)
)
</div>
</body>
</html>
Risorse aggiuntive
- Introduzione alla programmazione Web ASP.NET utilizzando la sintassi Razor
- Clausola SQL WHERE nel sito W3Schools
- Articolo Definizioni dei metodi nel sito W3C