Introduzione a Pagine Web ASP.NET - Nozioni di base sul modulo HTML

di Tom FitzMacken

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:

Pagina Film con genere e ricerca titolo

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:

Modulo HTML di base come eseguito il rendering nel browser

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'operazione GET per richiedere la pagina desiderata. Se la pagina include grafica, il browser esegue operazioni aggiuntive GET per ottenere le immagini. Se l'operazione GET deve passare informazioni al server, le informazioni vengono passate come parte dell'URL nella stringa di query.
  • POST. Il browser invia una POST richiesta per inviare dati da aggiungere o modificare nel server. Ad esempio, il POST 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'operazione POST . In un'operazione POST , 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 GETPOST 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 GETPOST 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:

Pagina Film con casella di ricerca per Genere

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> denominato searchGenre.
  • 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 al IsEmpty 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 è una POST richiesta.
  • Request.QueryString fornisce solo i valori nella stringa di query dell'URL. In un URL come http://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, @2e 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 al db.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:

Presentazione della pagina Film dopo la ricerca del genere 'Comedies'

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 Requestvalue 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:

Pagina che mostra che la casella di testo ha memorizzato la voce precedente

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 e selectCommand 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 e searchTitleil codice imposta searchTerm il valore da cercare. Questi blocchi di codice sono impostati anche su selectCommand un comando SQL appropriato per la ricerca.
  • Il db.Query metodo viene richiamato una sola volta, usando qualsiasi comando SQL in selectedCommand e qualsiasi valore si trova in searchTerm. Se non è presente alcun termine di ricerca (nessun genere e nessuna parola del titolo), il valore di searchTerm è 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.

Presentazione della pagina Film dopo la ricerca di 'The' 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.

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