Jednostránková aplikace: šablona KnockoutJS
Šablona Knockout MVC je součástí ASP.NET and Web Tools 2012.2.
Aktualizace ASP.NET and Web Tools 2012.2 obsahuje šablonu Single-Page Application (SPA) pro ASP.NET MVC 4. Tato šablona je navržená tak, abyste mohli rychle začít vytvářet interaktivní webové aplikace na straně klienta.
"Jednostránková aplikace" (SPA) je obecný termín pro webovou aplikaci, která načte jednu stránku HTML a pak stránku dynamicky aktualizuje, místo aby načítala nové stránky. Po počátečním načtení stránky bude SPA komunikovat se serverem prostřednictvím požadavků AJAX.
AJAX není nic nového, ale dnes existují javascriptové architektury, které usnadňují sestavení a údržbu velkých sofistikovaných aplikací SPA. Html 5 a CSS3 také usnadňují vytváření bohatých uživatelských rozhraní.
Abyste mohli začít, šablona SPA vytvoří ukázkovou aplikaci "Seznam úkolů". V tomto kurzu se podíváme na šablonu s průvodcem. Nejprve se podíváme na samotnou aplikaci seznamu úkolů a pak prozkoumáme technologické části, díky kterým funguje.
Vytvoření nového projektu šablony SPA
Požadavky:
- Visual Studio 2012 nebo Visual Studio Express 2012 pro web
- ASP.NET Web Tools 2012.2. Aktualizaci můžete nainstalovat tady.
Spusťte Visual Studio a na úvodní stránce vyberte Nový projekt . Nebo v nabídce Soubor vyberte Nový a pak Projekt.
V podokně Šablony vyberte Nainstalované šablony a rozbalte uzel Visual C# . V části Visual C# vyberte Web. V seznamu šablon projektů vyberte ASP.NET webová aplikace MVC 4. Pojmenujte projekt a klikněte na OK.
V průvodci Novým projektem vyberte Jednostránková aplikace.
Stisknutím klávesy F5 aplikaci sestavíte a spustíte. Při prvním spuštění aplikace se zobrazí přihlašovací obrazovka.
Klikněte na odkaz Zaregistrovat se a vytvořte nového uživatele.
Po přihlášení aplikace vytvoří výchozí seznam úkolů se dvěma položkami. Kliknutím na Přidat seznam úkolů můžete přidat nový seznam.
Přejmenujte seznam, přidejte do seznamu položky a zaškrtněte je. Můžete také odstranit položky nebo celý seznam. Změny se automaticky zachovají do databáze na serveru (v tomto okamžiku se ve skutečnosti jedná o LocalDB, protože aplikaci spouštíte místně).
Architektura šablony SPA
Tento diagram znázorňuje hlavní stavební bloky aplikace.
Na straně serveru ASP.NET MVC obsluhuje kód HTML a také zpracovává ověřování na základě formulářů.
ASP.NET webové rozhraní API zpracovává všechny požadavky, které se týkají seznamu úkolů a položek ToDoLists, včetně získání, vytvoření, aktualizace a odstranění. Klient si vyměňuje data s webovým rozhraním API ve formátu JSON.
Entity Framework (EF) je vrstva O/RM. Zprostředkuje mezi objektově orientovaným světem ASP.NET a podkladovou databází. Databáze používá LocalDB, ale můžete to změnit v souboru Web.config. Obvykle byste localDB použili k místnímu vývoji a pak ho nasadili do databáze SQL na serveru pomocí migrace EF s prvním kódem.
Na straně klienta knihovna Knockout.js zpracovává aktualizace stránek z požadavků AJAX. Knockout používá datovou vazbu k synchronizaci stránky s nejnovějšími daty. Díky tomu nemusíte psát žádný kód, který vás provede daty JSON a aktualizuje dom. Místo toho vložíte deklarativní atributy do HTML, které říkají Knockout, jak prezentovat data.
Velkou výhodou této architektury je, že odděluje prezentační vrstvu od logiky aplikace. Část webového rozhraní API můžete vytvořit, aniž byste cokoli věděli o tom, jak bude vaše webová stránka vypadat. Na straně klienta vytvoříte "model zobrazení", který bude tato data reprezentovat, a model zobrazení použije Knockout k vytvoření vazby s kódem HTML. To vám umožní snadno změnit kód HTML bez změny modelu zobrazení. (Na Knockout se podíváme později.)
Modely
V projektu sady Visual Studio obsahuje složka Models modely, které se používají na straně serveru. (Existují také modely na straně klienta; k těm se dostaneme.)
TodoItem, TodoList
Toto jsou databázové modely pro Entity Framework Code First. Všimněte si, že tyto modely mají vlastnosti, které na sebe vzájemně ukazují. ToDoList
obsahuje kolekci ToDoItems a každý z nich ToDoItem
má odkaz zpět na nadřazený ToDoList. Tyto vlastnosti se nazývají navigační vlastnosti a představují relaci seznamu úkolů 1:N a jeho položky úkolů.
Třída ToDoItem
také používá atribut [ForeignKey] k určení, že ToDoListId
je cizí klíč do ToDoList
tabulky. To ef sděluje, že má do databáze přidat omezení cizího klíče.
[ForeignKey("TodoList")]
public int TodoListId { get; set; }
public virtual TodoList TodoList { get; set; }
TodoItemDto, TodoListDto
Tyto třídy definují data, která budou odeslána klientovi. "DTO" znamená "objekt přenosu dat". DTO definuje, jak se entity serializují do FORMÁTU JSON. Obecně platí, že existuje několik důvodů, proč používat DTO:
- Chcete-li řídit, které vlastnosti jsou serializovány. DTO může obsahovat podmnožinu vlastností z doménového modelu. Můžete to udělat z bezpečnostních důvodů (kvůli skrytí citlivých dat) nebo jednoduše kvůli snížení množství odesílaných dat.
- Chcete-li změnit tvar dat – například zploštět složitější datovou strukturu.
- K tomu, aby jakákoli obchodní logika byla mimo DTO (oddělení zájmů).
- Pokud vaše doménové modely nelze z nějakého důvodu serializovat. Například cyklické odkazy mohou způsobit problémy při serializaci objektu Existují způsoby, jak tento problém vyřešit ve webovém rozhraní API (viz Zpracování cyklických odkazů na objekty); ale použití DTO jednoduše tento problém úplně vyhne.
V šabloně SPA obsahují objekty DTO stejná data jako doménové modely. Jsou však stále užitečné, protože se vyhýbají cyklických odkazům z navigačních vlastností a demonstrují obecný vzor DTO.
AccountModels.cs
Tento soubor obsahuje modely pro členství na webu. Třída UserProfile
definuje schéma pro profily uživatelů v databázi členství. (V tomto případě je jedinou informací ID uživatele a uživatelské jméno.) Ostatní třídy modelu v tomto souboru slouží k vytvoření formulářů pro registraci a přihlášení uživatele.
Entity Framework
Šablona SPA používá EF Code First. Ve vývoji Code First definujete modely nejprve v kódu a pak EF použije model k vytvoření databáze. Ef můžete použít také s existující databází (Database First).
Třída TodoItemContext
ve složce Models je odvozena z DbContext. Tato třída poskytuje "připevnění" mezi modely a EF. Obsahuje TodoItemContext
kolekci ToDoItem
a kolekci TodoList
. K dotazování databáze stačí na tyto kolekce napsat dotaz LINQ. Tady je příklad, jak můžete vybrat všechny seznamy úkolů pro uživatele Alice:
TodoItemContext db = new TodoItemContext();
IEnumerable<TodoList> lists =
from td in db.TodoLists where td.UserId == "Alice" select td;
Můžete také přidat nové položky do kolekce, aktualizovat položky nebo odstranit položky z kolekce a zachovat změny v databázi.
kontrolery webového rozhraní API ASP.NET
Ve webovém rozhraní API ASP.NET jsou kontrolery objekty, které zpracovávají požadavky HTTP. Jak už bylo zmíněno, šablona SPA používá webové rozhraní API k povolení operací CRUD na ToDoList
instancích a ToDoItem
. Kontrolery se nacházejí ve složce Kontrolery řešení.
TodoController
: Zpracovává požadavky HTTP pro položky úkolů.TodoListController
: Zpracovává požadavky HTTP pro seznamy úkolů.
Tyto názvy jsou důležité, protože webové rozhraní API odpovídá cestě URI k názvu kontroleru. (Informace o tom, jak webové rozhraní API směruje požadavky HTTP do kontrolerů, najdete v tématu Směrování v ASP.NET webovém rozhraní API.)
Pojďme se podívat na ToDoListController
třídu . Obsahuje jeden datový člen:
private TodoItemContext db = new TodoItemContext();
Slouží TodoItemContext
ke komunikaci s EF, jak je popsáno výše. Metody v kontroleru implementují operace CRUD. Webové rozhraní API mapuje požadavky HTTP z klienta na metody kontroleru následujícím způsobem:
Požadavek HTTP | Controller – metoda | Description |
---|---|---|
GET /api/todo | GetTodoLists |
Získá kolekci seznamů úkolů. |
GET /api/todo/id | GetTodoList |
Získá seznam úkolů podle ID. |
PUT /api/todo/id | PutTodoList |
Aktualizace seznam úkolů. |
POST /api/todo | PostTodoList |
Vytvoří nový seznam úkolů. |
DELETE /api/todo/id | DeleteTodoList |
Odstraní seznam TODO. |
Všimněte si, že identifikátory URI pro některé operace obsahují zástupné symboly pro hodnotu ID. Pokud například chcete odstranit seznam s ID 42, identifikátor URI je /api/todo/42
.
Další informace o použití webového rozhraní API pro operace CRUD najdete v tématu Vytvoření webového rozhraní API, které podporuje operace CRUD. Kód tohoto kontroleru je poměrně jednoduchý. Tady je několik zajímavých bodů:
- Metoda
GetTodoLists
používá dotaz LINQ k filtrování výsledků podle ID přihlášeného uživatele. Uživatel tak uvidí jenom data, která mu patří. Všimněte si také, že příkaz Select slouží k převodu instancí naToDoList
TodoListDto
instance. - Metody PUT a POST zkontrolují stav modelu před úpravou databáze. Pokud ModelState.IsValid je false, tyto metody vrátí HTTP 400, Chybný požadavek. Další informace o ověřování modelu ve webovém rozhraní API najdete v tématu Ověření modelu.
- Třída kontroleru je také opatřena atributem [Authorize]. Tento atribut zkontroluje, jestli je požadavek HTTP ověřený. Pokud požadavek není ověřený, klient obdrží HTTP 401, Neautorizováno. Další informace o ověřování najdete v tématu Ověřování a autorizace v ASP.NET webovém rozhraní API.
Třída TodoController
je velmi podobná TodoListController
třídě . Největší rozdíl spočívá v tom, že nedefinuje žádné metody GET, protože klient získá položky úkolů spolu se seznamem úkolů.
Kontrolery a zobrazení MVC
Kontrolery MVC jsou také umístěné ve složce Kontrolery řešení. HomeController
vykreslí hlavní kód HTML pro aplikaci. Zobrazení kontroleru Home je definováno v souboru Views/Home/Index.cshtml. Zobrazení Domů vykreslí jiný obsah v závislosti na tom, jestli je uživatel přihlášený:
@if (@User.Identity.IsAuthenticated)
{
// ....
}
Když jsou uživatelé přihlášení, zobrazí se jim hlavní uživatelské rozhraní. V opačném případě se jim zobrazí přihlašovací panel. Upozorňujeme, že toto podmíněné vykreslování probíhá na straně serveru. Nikdy se nepokoušejte skrýt citlivý obsah na straně klienta – vše, co odešlete v odpovědi HTTP, uvidí někdo, kdo sleduje nezpracované zprávy HTTP.
Client-Side JavaScriptu a Knockout.js
Teď přejděme ze serverové strany aplikace na klienta. Šablona SPA používá kombinaci jQuery a Knockout.js k vytvoření plynulého interaktivního uživatelského rozhraní. Knockout.js je javascriptová knihovna, která usnadňuje vytvoření vazby HTML na data. Knockout.js používá vzor s názvem Model-View-ViewModel.
- Model jsou doménová data (seznamy ToDo a položky ToDo).
- Zobrazení je dokument HTML.
- View-model je objekt JavaScriptu, který obsahuje data modelu. Model zobrazení je abstrakcí kódu uživatelského rozhraní. Nemá žádné znalosti o reprezentaci HTML. Místo toho představuje abstraktní funkce zobrazení, například "seznam položek úkolů".
Zobrazení je svázané s modelem zobrazení. Aktualizace k modelu zobrazení se v zobrazení automaticky projeví. Vazby fungují i v opačném směru. Události v modelu DOM (například kliknutí) jsou data svázaná s funkcemi v modelu zobrazení, které aktivují volání AJAX.
Šablona SPA uspořádá JavaScript na straně klienta do tří vrstev:
- todo.datacontext.js: Odesílá požadavky AJAX.
- todo.model.js: Definuje modely.
- todo.viewmodel.js: Definuje model zobrazení.
Tyto soubory skriptů se nacházejí ve složce Scripts/app řešení.
todo.datacontext zpracovává všechna volání AJAX kontrolerů webového rozhraní API. (Volání AJAX pro přihlášení jsou definována jinde, v ajaxlogin.js.)
todo.model.js definuje modely na straně klienta (prohlížeče) pro seznamy úkolů. Existují dvě třídy modelu: todoItem a todoList.
Mnoho vlastností v modelových třídách je typu "ko.observable". Pozorovatelné jsou, jak Knockout dělá své kouzlo. Z dokumentace Knockout: Pozorovatelný je javascriptový objekt, který může odběratele upozornit na změny. Když se hodnota pozorovatelného změní, Knockout aktualizuje všechny elementy HTML, které jsou vázány na tyto pozorovatelné. Například vlastnost todoItem má pozorovatelné vlastnosti pro název a isDone:
self.title = ko.observable(data.title);
self.isDone = ko.observable(data.isDone);
Můžete se také přihlásit k odběru pozorovatelného v kódu. Například třída todoItem odebírá změny ve vlastnostech "isDone" a "title":
saveChanges = function () {
return datacontext.saveChangedTodoItem(self);
};
// Auto-save when these properties change
self.isDone.subscribe(saveChanges);
self.title.subscribe(saveChanges);
Zobrazit model
Model zobrazení je definován v todo.viewmodel.js. Model zobrazení je centrálním bodem, kde aplikace sváže elementy stránky HTML s daty domény. V šabloně SPA obsahuje model zobrazení pozorovatelné pole todoLists. Následující kód v modelu zobrazení říká Knockout, aby použil vazby:
ko.applyBindings(window.todoApp.todoListViewModel);
HTML a datová vazba
Hlavní kód HTML stránky je definovaný v souboru Views/Home/Index.cshtml. Vzhledem k tomu, že používáme datovou vazbu, html je pouze šablona toho, co se skutečně vykresluje. Knockout používá deklarativní vazby. Prvky stránky svážete s daty přidáním atributu "data-bind" do elementu. Tady je velmi jednoduchý příklad z dokumentace k Knockoutu:
<p>There are <span data-bind="text: myItems().count"></span> items<p>
V tomto příkladu Knockout aktualizuje obsah elementu <span> hodnotou myItems.count()
. Kdykoli se tato hodnota změní, Knockout dokument aktualizuje.
Knockout poskytuje řadu různých typů vazeb. Tady jsou některé vazby použité v šabloně SPA:
- foreach: Umožňuje iterovat smyčku a použít stejný kód pro každou položku v seznamu. Slouží k vykreslení seznamů úkolů a položek úkolů. Vazby se v předeachu použijí na prvky seznamu.
- visible: Používá se k přepínání viditelnosti. Pokud je kolekce prázdná, skryjte značky nebo zviditelněte chybovou zprávu.
- value: Slouží k naplnění hodnot formuláře.
- click: Vytvoří vazbu události click na funkci v modelu zobrazení.
Ochrana proti CSRF
CsrF (Cross-Site Request Forgery) je útok, kdy škodlivý web odešle požadavek na ohrožený web, na kterém je uživatel aktuálně přihlášený. Aby se zabránilo útokům CSRF, ASP.NET MVC používá tokeny proti padělání, označované také jako ověřovací tokeny požadavků. Jde o to, že server vloží náhodně vygenerovaný token na webovou stránku. Když klient odešle data na server, musí tuto hodnotu zahrnout do zprávy požadavku.
Tokeny proti padělání fungují, protože škodlivá stránka nemůže číst tokeny uživatele kvůli zásadám stejného původu. (Zásady stejného původu brání dokumentům hostovaným na dvou různých webech v přístupu k obsahu ostatních.)
ASP.NET MVC poskytuje integrovanou podporu tokenů proti padělání prostřednictvím třídy AntiForgery a atributu [ValidateAntiForgeryToken]. V současné době tato funkce není součástí webového rozhraní API. Šablona SPA ale obsahuje vlastní implementaci webového rozhraní API. Tento kód je definován ve ValidateHttpAntiForgeryTokenAttribute
třídě, která se nachází ve složce Filters řešení. Další informace o anti-CSRF ve webovém rozhraní API najdete v tématu Prevence útoků CSRF (Cross-Site Request Forgery).
Závěr
Šablona SPA je navržená tak, abyste mohli rychle začít psát moderní interaktivní webové aplikace. Používá knihovnu Knockout.js k oddělení prezentace (značky HTML) od logiky dat a aplikace. Knockout ale není jediná javascriptová knihovna, kterou můžete použít k vytvoření SPA. Pokud chcete prozkoumat některé další možnosti, podívejte se na šablony SPA vytvořené komunitou.