Udostępnij za pośrednictwem


Wprowadzenie do stron internetowych ASP.NET — podstawy formularza HTML

– autor Tom FitzMacken

W tym samouczku przedstawiono podstawowe informacje na temat tworzenia formularza wejściowego oraz sposobu obsługi danych wejściowych użytkownika podczas korzystania z ASP.NET Web Pages (Razor). Teraz, gdy masz już bazę danych, będziesz używać swoich umiejętności formularzy, aby umożliwić użytkownikom znajdowanie określonych filmów w bazie danych. Przyjęto założenie, że seria została ukończona przez wprowadzenie do wyświetlania danych przy użyciu ASP.NET stron internetowych.

Zawartość:

  • Jak utworzyć formularz przy użyciu standardowych elementów HTML.
  • Jak odczytać dane wejściowe użytkownika w formularzu.
  • Jak utworzyć zapytanie SQL, które selektywnie pobiera dane przy użyciu terminu wyszukiwania, który użytkownik dostarcza.
  • Jak mieć pola na stronie "zapamiętaj", co użytkownik wprowadził.

Omówione funkcje/technologie:

  • Obiekt Request.
  • Klauzula SQL Where .

Co utworzysz

W poprzednim samouczku utworzono bazę danych, dodano do niej dane, a następnie użyto WebGrid pomocnika do wyświetlenia danych. W tym samouczku dodasz pole wyszukiwania, które pozwala znaleźć filmy określonego gatunku lub którego tytuł zawiera dowolne wprowadzone słowo. (Na przykład będzie można znaleźć wszystkie filmy, których gatunek to "Akcja" lub którego tytuł zawiera "Harry" lub "Adventure").

Po zakończeniu pracy z tym samouczkiem będziesz mieć stronę podobną do następującej:

Strona Filmów z wyszukiwaniem gatunku i tytułu

Część listy na stronie jest taka sama jak w ostatnim samouczku — siatce. Różnica będzie taka, że siatka będzie wyświetlać tylko wyszukiwane filmy.

Informacje o formularzach HTML

(Jeśli masz doświadczenie z tworzeniem formularzy HTML i różnicą między GET i POST, możesz pominąć tę sekcję).

Formularz zawiera elementy wejściowe użytkownika — pola tekstowe, przyciski, przyciski radiowe, pola wyboru, listy rozwijane itd. Użytkownicy wypełniają te kontrolki lub dokonają wyborów, a następnie przesyłają formularz, klikając przycisk.

Podstawowa składnia HTML formularza jest zilustrowana w tym przykładzie:

<form method="post">
  <input type="text" name="name" value="" />
  <br/>
  <input type="submit" name="submit" value="Submit" />
</form>

Po uruchomieniu tej adiustacji na stronie zostanie utworzony prosty formularz, który wygląda podobnie do poniższej ilustracji:

Podstawowy formularz HTML renderowany w przeglądarce

Element <form> ujęta w elementy HTML do przesłania. (Łatwo popełnić błąd polega na dodaniu elementów do strony, ale następnie zapomnieć umieścić je wewnątrz <form> elementu. W takim przypadku nic nie zostanie przesłane). Atrybut method informuje przeglądarkę, jak przesłać dane wejściowe użytkownika. Należy ustawić tę opcję na post wartość , jeśli przeprowadzasz aktualizację na serwerze lub get pobierasz dane z serwera.

Porada

Get, POST i HTTP Verb Safety

HTTP, protokół używany przez przeglądarki i serwery do wymiany informacji, jest niezwykle prosty w podstawowych operacjach. Przeglądarki używają tylko kilku zleceń, aby wysyłać żądania do serwerów. Podczas pisania kodu dla Internetu warto zrozumieć te czasowniki oraz sposób ich używania przez przeglądarkę i serwer. Najdalej od najczęściej używanych czasowników są następujące:

  • GET. Przeglądarka używa tego zlecenia, aby pobrać coś z serwera. Na przykład podczas wpisywania adresu URL w przeglądarce przeglądarka wykonuje operację GET żądania żądanej strony. Jeśli strona zawiera grafikę, przeglądarka wykonuje dodatkowe GET operacje w celu pobrania obrazów. GET Jeśli operacja musi przekazać informacje do serwera, informacje są przekazywane jako część adresu URL w ciągu zapytania.
  • POST. Przeglądarka wysyła POST żądanie w celu przesłania danych do dodania lub zmiany na serwerze. Na przykład POST czasownik służy do tworzenia rekordów w bazie danych lub zmieniania istniejących. W większości przypadków po wypełnieniu formularza i kliknięciu przycisku przesyłania przeglądarka wykonuje operację POST . POST W operacji dane przekazywane do serwera są w treści strony.

Ważną różnicą między tymi czasownikami jest to, że GET operacja nie powinna zmieniać niczego na serwerze — lub umieścić je w nieco bardziej abstrakcyjny sposób, GET operacja nie powoduje zmiany stanu na serwerze. Możesz wykonać operację GET na tych samych zasobach tyle razy, ile chcesz, a te zasoby nie ulegają zmianie. GET(Często mówi się, że operacja jest "bezpieczna", lub używać terminu technicznego, jest idempotentna). Oczywiście żądanie POST zmienia coś na serwerze za każdym razem, gdy wykonujesz operację.

Dwa przykłady pomogą zilustrować to rozróżnienie. Podczas wyszukiwania przy użyciu aparatu, takiego jak Bing lub Google, wypełniasz formularz składający się z jednego pola tekstowego, a następnie klikasz przycisk wyszukiwania. Przeglądarka wykonuje operację GET z wartością wprowadzoną w polu przekazanym jako część adresu URL. GET Użycie operacji dla tego typu formularza jest w porządku, ponieważ operacja wyszukiwania nie zmienia żadnych zasobów na serwerze, po prostu pobiera informacje.

Teraz rozważmy proces zamawiania czegoś online. Wypełnij szczegóły zamówienia, a następnie kliknij przycisk Prześlij. Ta operacja będzie żądaniem POST , ponieważ operacja spowoduje zmiany na serwerze, takie jak nowy rekord zamówienia, zmiana informacji o koncie i być może wiele innych zmian. GET W przeciwieństwie do operacji nie można powtórzyć POST żądania — jeśli to zrobiono, za każdym razem, gdy ponownie prześlij żądanie, wygenerujesz nowe zamówienie na serwerze. (W takich przypadkach witryny internetowe często ostrzegają, aby nie klikać przycisku przesyłania więcej niż raz lub wyłączać przycisk przesyłania, aby przypadkowo nie przesyłać formularza).

W trakcie tego samouczka użyjesz zarówno GET operacji, jak i POST operacji do pracy z formularzami HTML. W każdym przypadku wyjaśnimy, dlaczego używane czasowniki są odpowiednie.

(Aby dowiedzieć się więcej na temat czasowników HTTP, zobacz artykuł Definicje metod w witrynie W3C).

Większość elementów wejściowych użytkownika to elementy HTML <input> . Wyglądają jak <input type="type" name="name">, w przypadku, gdy typ wskazuje odpowiedni rodzaj kontrolki wprowadzania danych przez użytkownika. Są to typowe elementy:

  • Pole tekstowe: <input type="text">
  • Pole wyboru: <input type="check">
  • Przycisk radiowy: <input type="radio">
  • Przycisk: <input type="button">
  • Przycisk Prześlij: <input type="submit">

Możesz również użyć <textarea> elementu , aby utworzyć wielowierszowe pole tekstowe i <select> element w celu utworzenia listy rozwijanej lub listy przewijanej. (Aby uzyskać więcej informacji na temat elementów formularza HTML, zobacz Formularze HTML i dane wejściowe w witrynie W3Schools).

Atrybut name jest bardzo ważny, ponieważ nazwa jest sposobem uzyskania wartości elementu później, jak zobaczysz wkrótce.

Interesującą częścią jest to, co ty, deweloper strony, robisz z danymi wejściowymi użytkownika. Nie ma wbudowanego zachowania skojarzonego z tymi elementami. Zamiast tego musisz uzyskać wartości wprowadzone lub wybrane przez użytkownika i zrobić z nimi coś. Z tego samouczka dowiesz się.

Porada

HTML5 i formularze wejściowe

Jak można wiedzieć, kod HTML jest w przejściu, a najnowsza wersja (HTML5) obejmuje obsługę bardziej intuicyjnych sposobów wprowadzania informacji przez użytkowników. Na przykład w kodzie HTML5 (deweloper strony) możesz wskazać stronę, na której użytkownik ma wprowadzić datę. Przeglądarka może następnie automatycznie wyświetlać kalendarz, zamiast wymagać od użytkownika ręcznego wprowadzenia daty. Jednak kod HTML5 jest nowy i nie jest jeszcze obsługiwany we wszystkich przeglądarkach.

ASP.NET Stron sieci Web obsługuje dane wejściowe HTML5 w zakresie, w jakim przeglądarka użytkownika. Aby zapoznać się z nowymi atrybutami <input> elementu w kodzie HTML5, zobacz Atrybut typu danych wejściowych> HTML < w witrynie W3Schools.

Tworzenie formularza

W programie WebMatrix w obszarze roboczym Pliki otwórz stronę Movies.cshtml .

Po tagu zamykającym </h1> i przed tagiem otwierania grid.GetHtml<div> wywołania dodaj następujące znaczniki:

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

Ten znacznik tworzy formularz z polem tekstowym o nazwie searchGenre i przyciskiem przesyłania. Pole tekstowe i przycisk przesyłania są ujęte w <form> element, którego method atrybut jest ustawiony na getwartość . (Pamiętaj, że jeśli nie umieścisz pola tekstowego i przycisku prześlij wewnątrz <form> elementu, nic nie zostanie przesłane po kliknięciu przycisku). Czasownik jest GET używany tutaj, ponieważ tworzysz formularz, który nie wprowadza żadnych zmian na serwerze — powoduje to jedynie wyszukiwanie. (W poprzednim samouczku użyto post metody , czyli sposobu przesyłania zmian do serwera. Zobaczysz to ponownie w następnym samouczku.

Uruchom stronę. Chociaż nie zdefiniowano żadnego zachowania dla formularza, możesz zobaczyć, jak wygląda:

Strona filmów z polem wyszukiwania dla gatunku

Wprowadź wartość w polu tekstowym, na przykład "Komedia". Następnie kliknij pozycję Wyszukaj gatunek.

Zanotuj adres URL strony. Ponieważ atrybut elementu method został ustawiony <form> na getwartość , wprowadzona wartość jest teraz częścią ciągu zapytania w adresie URL, w następujący sposób:

http://localhost:45661/Movies.cshtml?searchGenre=Comedy

Odczytywanie wartości formularza

Strona zawiera już kod, który pobiera dane bazy danych i wyświetla wyniki w siatce. Teraz musisz dodać kod, który odczytuje wartość pola tekstowego, aby można było uruchomić zapytanie SQL zawierające termin wyszukiwania.

Ponieważ ustawisz metodę formularza na get, możesz odczytać wartość, która została wprowadzona do pola tekstowego, używając kodu podobnego do następującego:

var searchTerm = Request.QueryString["searchGenre"];

Request.QueryString Obiekt (QueryStringwłaściwość Request obiektu) zawiera wartości elementów przesłanych w ramach GET operacji. Właściwość Request.QueryString zawiera kolekcję (listę) wartości przesłanych w formularzu. Aby uzyskać dowolną pojedynczą wartość, należy określić nazwę żądanego elementu. Dlatego musisz mieć name atrybut w <input> elemecie (searchTerm), który tworzy pole tekstowe. (Aby uzyskać więcej informacji na temat Request obiektu, zobacz pasek boczny później).

Wystarczy odczytać wartość pola tekstowego. Ale jeśli użytkownik w ogóle nic nie wprowadzi w polu tekstowym, ale mimo to kliknął pozycję Wyszukaj , możesz zignorować to kliknięcie, ponieważ nie ma nic do wyszukania.

Poniższy kod jest przykładem, który pokazuje, jak zaimplementować te warunki. (Nie musisz jeszcze dodawać tego kodu; zrobisz to za chwilę).

if(!Request.QueryString["searchGenre"].IsEmpty() ) {
     // Do something here
}

Test rozkłada się w następujący sposób:

  • Pobierz wartość , Request.QueryString["searchGenre"]czyli wartość, która została wprowadzona do <input> elementu o nazwie searchGenre.
  • Dowiedz się, czy jest ona pusta przy użyciu IsEmpty metody . Ta metoda jest standardowym sposobem określenia, czy coś (na przykład element formularza) zawiera wartość. Ale naprawdę, obchodzi cię tylko wtedy, gdy nie jest pusty, dlatego ...
  • ! Dodaj operator przed testemIsEmpty. (Operator ! oznacza logiczny NOT).

W języku angielskim cały if warunek przekłada się na następujące: Jeśli element searchGenre formularza nie jest pusty, to ...

Ten blok ustawia etap tworzenia zapytania używającego terminu wyszukiwania. Zrobisz to w następnej sekcji.

Porada

Obiekt żądania

Obiekt Request zawiera wszystkie informacje wysyłane przez przeglądarkę do aplikacji po zażądaniu lub przesłaniu strony. Ten obiekt zawiera wszelkie informacje podane przez użytkownika, takie jak wartości pól tekstowych lub plik do przekazania. Zawiera również wszelkiego rodzaju dodatkowe informacje, takie jak pliki cookie, wartości w ciągu zapytania adresu URL (jeśli istnieje), ścieżka pliku strony, która jest uruchomiona, typ przeglądarki używanej przez użytkownika, lista języków ustawionych w przeglądarce i wiele innych.

Obiekt Request jest kolekcją (listą) wartości. Otrzymasz pojedynczą wartość z kolekcji, określając jej nazwę:

var someValue = Request["name"];

Obiekt Request uwidacznia kilka podzestawów. Na przykład:

  • Request.Form daje wartości z elementów wewnątrz przesłanego <form> elementu, jeśli żądanie jest żądaniem POST .
  • Request.QueryString daje tylko wartości w ciągu zapytania adresu URL. (W adresie URL, na przykład http://mysite/myapp/page?searchGenre=action&page=2, ?searchGenre=action&page=2 sekcja adresu URL jest ciągiem zapytania).
  • Request.Cookies kolekcja zapewnia dostęp do plików cookie wysyłanych przez przeglądarkę.

Aby uzyskać wartość, którą znasz, znajduje się w przesłanym formularzu, możesz użyć polecenia Request["name"]. Alternatywnie można użyć bardziej określonych wersji Request.Form["name"] (dla POST żądań) lub Request.QueryString["name"] (w przypadku GET żądań). Oczywiście nazwa to nazwa elementu do pobrania.

Nazwa elementu, który chcesz uzyskać, musi być unikatowa w używanej kolekcji. Request Dlatego obiekt udostępnia podzestawy, takie jak Request.Form i Request.QueryString. Załóżmy, że strona zawiera element formularza o nazwie userName , a także plik cookie o nazwie userName. Jeśli otrzymasz Request["userName"]polecenie , jest niejednoznaczne, czy chcesz uzyskać wartość formularza, czy plik cookie. Jeśli jednak uzyskasz Request.Form["userName"] wartość lub Request.Cookie["userName"], masz jawną wartość, która ma być pobierana.

Dobrym rozwiązaniem jest użycie podzbioru Request , który cię interesuje, na przykład Request.Form lub Request.QueryString. W przypadku prostych stron, które tworzysz w tym samouczku, prawdopodobnie nie ma to żadnej różnicy. Jednak podczas tworzenia bardziej złożonych stron przy użyciu jawnej wersji Request.Form lub Request.QueryString może pomóc uniknąć problemów, które mogą wystąpić, gdy strona zawiera formularz (lub wiele formularzy), pliki cookie, wartości ciągu zapytania itd.

Tworzenie zapytania przy użyciu terminu wyszukiwania

Teraz, gdy wiesz, jak uzyskać wprowadzony przez użytkownika termin wyszukiwania, możesz utworzyć zapytanie, które go używa. Pamiętaj, że aby pobrać wszystkie elementy filmu z bazy danych, używasz zapytania SQL, które wygląda następująco:

SELECT * FROM Movies

Aby uzyskać tylko niektóre filmy, musisz użyć zapytania zawierającego klauzulę Where . Ta klauzula umożliwia ustawienie warunku, w którym wiersze są zwracane przez zapytanie. Oto przykład:

SELECT * FROM Movies WHERE Genre = 'Action'

Podstawowy format to WHERE column = value. Można użyć różnych operatorów oprócz tylko =, takich jak > ( większe niż), < (mniejsze niż), (nie równe), <=<> (mniejsze niż lub równe), itp., w zależności od tego, czego szukasz.

Jeśli zastanawiasz się, instrukcje SQL nie są uwzględniane wielkości liter — SELECT jest taka sama jak Select (lub nawet select). Jednak ludzie często tworzą wielkie litery słów kluczowych w instrukcji SQL, na przykład SELECT i WHERE, aby ułatwić odczytywanie.

Przekazywanie terminu wyszukiwania jako parametru

Wyszukiwanie określonego gatunku jest wystarczająco łatwe (WHERE Genre = 'Action'), ale chcesz mieć możliwość wyszukiwania dowolnego gatunku wprowadzonego przez użytkownika. W tym celu utworzysz zapytanie SQL zawierające symbol zastępczy wartości do wyszukania. Będzie wyglądać następująco:

SELECT * FROM Movies WHERE Genre = @0

Symbol zastępczy to @ znak, po którym następuje zero. Jak można się domyślać, zapytanie może zawierać wiele symboli zastępczych i nazwać @0je , @1, @2itp.

Aby skonfigurować zapytanie i przekazać ją do niej, należy użyć kodu w następujący sposób:

selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
selectedData = db.Query(selectCommand, Request.QueryString["searchGenre"]);

Ten kod jest podobny do tego, co zostało już zrobione, aby wyświetlić dane w siatce. Jedyne różnice to:

  • Zapytanie zawiera symbol zastępczy (WHERE Genre = @0").
  • Zapytanie jest umieszczane w zmiennej (selectCommand); przed przekazaniem zapytania bezpośrednio do db.Query metody.
  • Po wywołaniu db.Query metody należy przekazać zarówno zapytanie, jak i wartość do użycia dla symbolu zastępczego. (Jeśli zapytanie ma wiele symboli zastępczych, należy przekazać je wszystkie jako oddzielne wartości do metody).

W przypadku łączenia wszystkich tych elementów uzyskasz następujący kod:

if(!Request.QueryString["searchGenre"].IsEmpty() ) { 
    searchTerm = Request.QueryString["searchGenre"];
    selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
    selectedData = db.Query(selectCommand, searchTerm);
}

Uwaga

Ważne! Używanie symboli zastępczych (takich jak @0) do przekazywania wartości do polecenia SQL jest niezwykle ważne w przypadku zabezpieczeń. Sposób, w jaki widzisz go tutaj, z symbolami zastępczymi dla danych zmiennych, jest jedynym sposobem tworzenia poleceń SQL.

Nigdy nie skonstruuj instrukcji SQL, łącząc tekst literału (łączenie) i wartości uzyskiwane od użytkownika. Łączenie danych wejściowych użytkownika w instrukcji SQL powoduje otwarcie witryny na atak polegający na wstrzyknięciu kodu SQL , w którym złośliwy użytkownik przesyła wartości do strony, która hackuje bazę danych. (Więcej informacji można przeczytać w artykule Wstrzykiwanie kodu SQL w witrynie internetowej MSDN).

Aktualizowanie strony filmów przy użyciu kodu wyszukiwania

Teraz możesz zaktualizować kod w pliku Movies.cshtml . Aby rozpocząć, zastąp kod w bloku kodu w górnej części strony tym kodem:

var db = Database.Open("WebPagesMovies");
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";

Różnica polega na tym, że zapytanie zostało umieszczone w zmiennej selectCommand , która zostanie przekazana później db.Query . Umieszczenie instrukcji SQL w zmiennej umożliwia zmianę instrukcji, co zrobisz, aby wykonać wyszukiwanie.

Usunięto również te dwa wiersze, które zostaną przywrócone później:

var selectedData = db.Query("SELECT * FROM Movies");
var grid = new WebGrid(source: selectedData, rowsPerPage: 3);

Nie chcesz jeszcze uruchamiać zapytania (czyli wywołania db.Query) i nie chcesz jeszcze zainicjować WebGrid pomocnika. Te czynności zostaną przeprowadzone po zapoznaniu się z instrukcją SQL, która musi zostać uruchomiona.

Po przepisanym bloku możesz dodać nową logikę do obsługi wyszukiwania. Ukończony kod będzie wyglądać podobnie do poniższego. Zaktualizuj kod na stronie, aby był zgodny z tym przykładem:

@{
    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);
}

Strona działa teraz następująco. Za każdym razem, gdy strona jest uruchamiana, kod otwiera bazę danych, a selectCommand zmienna jest ustawiana na instrukcję SQL, która pobiera wszystkie rekordy z Movies tabeli. Kod inicjuje również zmienną searchTerm .

Jeśli jednak bieżące żądanie zawiera wartość elementu searchGenre , kod ustawia selectCommand na inne zapytanie — czyli na takie, które zawiera Where klauzulę wyszukiwania gatunku. Ustawia również searchTerm wartość dowolnego przekazanego pola wyszukiwania (co może być niczym).

Niezależnie od tego, która instrukcja SQL znajduje się w selectCommandelemecie , kod wywołuje db.Query polecenie , aby uruchomić zapytanie, przekazując go niezależnie od tego, co znajduje się w elemecie searchTerm. Jeśli nie ma nic w searchTermelemecie , nie ma znaczenia, ponieważ w takim przypadku nie ma parametru, aby mimo to przekazać selectCommand wartość.

Na koniec kod inicjuje WebGrid pomocnika przy użyciu wyników zapytania, podobnie jak wcześniej.

Możesz to zobaczyć, umieszczając instrukcję SQL i termin wyszukiwania w zmiennych, dodaliśmy elastyczność do kodu. Jak zobaczysz w dalszej części tego samouczka, możesz użyć tej podstawowej platformy i nadal dodawać logikę dla różnych typów wyszukiwań.

Testowanie funkcji wyszukiwania według gatunku

W programie WebMatrix uruchom stronę Movies.cshtml . Zostanie wyświetlona strona z polem tekstowym dla gatunku.

Wprowadź gatunek wprowadzony dla jednego z rekordów testowych, a następnie kliknij przycisk Wyszukaj. Tym razem zobaczysz listę tylko filmów, które pasują do tego gatunku:

Lista stron filmów po wyszukaniu gatunku

Wprowadź inny gatunek i wyszukaj ponownie. Spróbuj wprowadzić gatunek przy użyciu wszystkich małych liter lub wszystkich wielkich liter, aby zobaczyć, że wyszukiwanie nie jest uwzględniane wielkości liter.

"Zapamiętanie" wprowadzonego przez użytkownika

Być może zauważysz, że po wprowadzeniu gatunku i kliknięciu pozycji Gatunek wyszukiwania zostanie wyświetlona lista dla tego gatunku. Jednak pole tekstowe wyszukiwania było puste — innymi słowy, nie pamiętało wprowadzonego elementu.

Ważne jest, aby zrozumieć, dlaczego takie zachowanie występuje. Podczas przesyłania strony przeglądarka wysyła żądanie do serwera internetowego. Gdy ASP.NET pobiera żądanie, tworzy zupełnie nowe wystąpienie strony, uruchamia w nim kod, a następnie ponownie renderuje stronę w przeglądarce. W efekcie jednak strona nie wie, że właśnie pracujesz z poprzednią wersją samego siebie. Wszystko, co wie, to, że dostał żądanie, które zawierało jakieś dane formularza.

Za każdym razem, gdy żądasz strony — zarówno po raz pierwszy, jak i przez przesłanie jej — otrzymujesz nową stronę. Serwer internetowy nie ma pamięci ostatniego żądania. Żadna z nich nie ASP.NET, a żadna z nich nie jest w przeglądarce. Jedynym połączeniem między tymi oddzielnymi wystąpieniami strony są wszystkie dane przesyłane między nimi. Jeśli na przykład prześlesz stronę, nowe wystąpienie strony może pobrać dane formularza wysłane przez wcześniejsze wystąpienie. (Innym sposobem przekazywania danych między stronami jest użycie plików cookie).

Formalnym sposobem opisania tej sytuacji jest stwierdzenie, że strony internetowe są bezstanowe. Serwery sieci Web i same strony oraz elementy na stronie nie utrzymują żadnych informacji o poprzednim stanie strony. Sieć Web została zaprojektowana w ten sposób, ponieważ utrzymywanie stanu poszczególnych żądań szybko wyczerpałoby zasoby serwerów internetowych, które często obsługują tysiące, a może nawet setki tysięcy żądań na sekundę.

Dlatego pole tekstowe było puste. Po przesłaniu strony ASP.NET utworzyć nowe wystąpienie strony i przejść przez kod i znaczniki. Nie było nic w tym kodzie, który powiedział ASP.NET, aby umieścić wartość w polu tekstowym. Więc ASP.NET nic nie zrobił, a pole tekstowe zostało renderowane bez wartości w nim.

Jest rzeczywiście łatwy sposób, aby obejść ten problem. Gatunek wprowadzony w polu tekstowym jest dostępny w kodzie — jest w nim .Request.QueryString["searchGenre"]

Zaktualizuj znaczniki dla pola tekstowego, aby value atrybut pobierał jego wartość z searchTermelementu , tak jak w tym przykładzie:

<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />

Na tej stronie można również ustawić value atrybut na zmienną searchTerm , ponieważ ta zmienna zawiera również wprowadzony gatunek. Jednak użycie obiektu do ustawienia atrybutu Requestvalue , jak pokazano tutaj, jest standardowym sposobem wykonania tego zadania. (Zakładając nawet, że chcesz to zrobić — w niektórych sytuacjach możesz renderować stronę bez wartości w polach. Wszystko zależy od tego, co się dzieje z twoją aplikacją).

Uwaga

Nie można "zapamiętać" wartości pola tekstowego używanego dla haseł. Byłoby to dziura w zabezpieczeniach, która umożliwia ludziom wypełnienie pola hasła przy użyciu kodu.

Uruchom ponownie stronę, wprowadź gatunek i kliknij pozycję Wyszukaj gatunek. Tym razem nie tylko zobaczysz wyniki wyszukiwania, ale pole tekstowe pamięta o tym, co wprowadzono po raz ostatni:

Strona przedstawiająca, że pole tekstowe

Wyszukiwanie dowolnych Word w tytule

Teraz możesz wyszukać dowolny gatunek, ale możesz również wyszukać tytuł. Trudno uzyskać tytuł dokładnie w prawo podczas wyszukiwania, więc zamiast tego możesz wyszukać słowo, które jest wyświetlane w dowolnym miejscu w tytule. Aby to zrobić w programie SQL, należy użyć LIKE operatora i składni, tak jak w następujący sposób:

SELECT * FROM Movies WHERE Title LIKE '%adventure%'

To polecenie pobiera wszystkie filmy, których tytuły zawierają "przygodę". W przypadku korzystania z LIKE operatora należy uwzględnić symbol % wieloznaczny w ramach terminu wyszukiwania. Wyszukiwanie oznacza "początek LIKE 'adventure%' przygody". (Technicznie oznacza to ciąg "przygoda", po którym następuje coś". Podobnie termin LIKE '%adventure' wyszukiwania oznacza "wszystko, po czym następuje ciąg "adventure", czyli inny sposób na powiedzenie "kończące się "przygodą".

W związku z tym termin LIKE '%adventure%' wyszukiwania oznacza "z przygodą" w dowolnym miejscu w tytule. (Technicznie, "wszystko w tytule, a następnie "przygoda", a następnie wszystko.")

<form> Wewnątrz elementu dodaj następujący znacznik bezpośrednio pod tagiem zamykającym dla wyszukiwania gatunku (tuż przed elementem zamykającym </div></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>

Kod do obsługi tego wyszukiwania jest podobny do kodu wyszukiwania gatunku LIKE , z wyjątkiem tego, że trzeba zebrać wyszukiwanie. Wewnątrz bloku kodu w górnej części strony dodaj ten if blok tuż po if bloku wyszukiwania gatunku:

if(!Request.QueryString["searchTitle"].IsEmpty() ) {
    selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
    searchTerm = "%" + Request["searchTitle"] + "%";
}

Ten kod używa tej samej logiki, którą pokazano wcześniej, z wyjątkiem tego, że wyszukiwanie używa operatora, a kod umieszcza ciąg "%" przed terminem LIKE wyszukiwania i po nim.

Zwróć uwagę, jak łatwo było dodać kolejne wyszukiwanie do strony. Wszystko, co musiałeś zrobić, to:

  • if Utwórz blok testowany, aby sprawdzić, czy odpowiednie pole wyszukiwania ma wartość.
  • Ustaw zmienną selectCommand na nową instrukcję SQL.
  • Ustaw zmienną searchTerm na wartość, która ma zostać przekazana do zapytania.

Oto kompletny blok kodu zawierający nową logikę wyszukiwania tytułów:

@{
    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);
}

Oto podsumowanie tego kodu:

  • Zmienne searchTerm i selectCommand są inicjowane u góry. Te zmienne mają zostać ustawione na odpowiedni termin wyszukiwania (jeśli istnieje) i odpowiednie polecenie SQL na podstawie tego, co użytkownik robi na stronie. Wyszukiwanie domyślne to prosty przypadek pobierania wszystkich filmów z bazy danych.
  • W testach dla searchGenre i searchTitlekod ustawia searchTerm wartość, którą chcesz wyszukać. Te bloki kodu są również ustawione selectCommand na odpowiednie polecenie SQL dla tego wyszukiwania.
  • Metoda db.Query jest wywoływana tylko raz, używając dowolnego polecenia SQL i selectedCommand dowolnej wartości w searchTerm. Jeśli nie ma terminu wyszukiwania (bez gatunku i żadnego słowa tytułu), wartość searchTerm jest pustym ciągiem. Nie ma to jednak znaczenia, ponieważ w takim przypadku zapytanie nie wymaga parametru.

Testowanie funkcji wyszukiwania tytułów

Teraz możesz przetestować ukończoną stronę wyszukiwania. Uruchom plik Movies.cshtml.

Wprowadź gatunek i kliknij pozycję Gatunek wyszukiwania. Siatka wyświetla filmy tego gatunku, jak wcześniej.

Wprowadź wyraz tytułu i kliknij pozycję Wyszukaj tytuł. Siatka wyświetla filmy o tym słowie w tytule.

Strona filmów po wyszukaniu

Pozostaw puste pola tekstowe i kliknij dowolny przycisk. Siatka wyświetla wszystkie filmy.

Łączenie zapytań

Możesz zauważyć, że wyszukiwania, które można wykonać, są wyłączne. Nie można jednocześnie wyszukiwać tytułu i gatunku, nawet jeśli oba pola wyszukiwania mają w nich wartości. Na przykład nie można wyszukać wszystkich filmów akcji, których tytuł zawiera "Adventure". (Ponieważ strona jest teraz kodowana, jeśli wprowadzisz wartości zarówno dla gatunku, jak i tytułu, wyszukiwanie tytułu będzie pierwszeństwo). Aby utworzyć wyszukiwanie, które łączy warunki, należy utworzyć zapytanie SQL, które ma składnię podobną do następującej:

SELECT * FROM Movies WHERE Genre = @0 AND Title LIKE @1

Konieczne byłoby uruchomienie zapytania przy użyciu instrukcji podobnej do poniższej (w przybliżeniu):

var selectedData = db.Query(selectCommand, searchGenre, searchTitle);

Tworzenie logiki w celu umożliwienia wielu permutacji kryteriów wyszukiwania może być nieco zaangażowane, jak widać. W związku z tym zatrzymamy się tutaj.

Następny etap

W następnym samouczku utworzysz stronę, która używa formularza, aby umożliwić użytkownikom dodawanie filmów do bazy danych.

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

Dodatkowe zasoby