Ćwiczenia praktyczne: tworzenie aplikacji jednostronicowej przy użyciu wzorca ASP.NET Web API i platformy Angular.js

Autor : Web Camps Team

Pobierz zestaw szkoleniowy obozów internetowych

To praktyczne laboratorium pokazuje, jak utworzyć aplikację jednostronicową (SPA) przy użyciu interfejsu API sieci Web ASP.NET i Angular.js dla ASP.NET 4.x.

W tym ręcznym laboratorium skorzystasz z tych technologii, aby zaimplementować Geek Quiz, trywii stronie internetowej opartej na koncepcji SPA. Najpierw zaimplementujesz warstwę usługi z ASP.NET internetowym interfejsem API, aby uwidocznić wymagane punkty końcowe w celu pobrania pytań testowych i zapisania odpowiedzi. Następnie utworzysz rozbudowany i dynamiczny interfejs użytkownika przy użyciu efektów transformacji AngularJS i CSS3.

W tradycyjnych aplikacjach internetowych klient (przeglądarka) inicjuje komunikację z serwerem, żądając strony. Następnie serwer przetwarza żądanie i wysyła kod HTML strony do klienta. W kolejnych interakcjach ze stroną — np. użytkownik przechodzi do linku lub przesyła formularz z danymi — nowe żądanie jest wysyłane do serwera, a przepływ jest uruchamiany ponownie: serwer przetwarza żądanie i wysyła nową stronę do przeglądarki w odpowiedzi na nową akcję żądaną przez klienta.

W Single-Page Aplikacji (SPA) cała strona jest ładowana w przeglądarce po początkowym żądaniu, ale kolejne interakcje odbywają się za pośrednictwem żądań Ajax. Oznacza to, że przeglądarka musi zaktualizować tylko część strony, która uległa zmianie; Nie ma potrzeby ponownego ładowania całej strony. Podejście SPA skraca czas podejmowanych przez aplikację do reagowania na działania użytkownika, co powoduje bardziej płynne wrażenia.

Architektura SPA obejmuje pewne wyzwania, które nie są obecne w tradycyjnych aplikacjach internetowych. Jednak pojawiające się technologie, takie jak internetowy interfejs API ASP.NET, struktury Języka JavaScript, takie jak AngularJS i nowe funkcje stylów udostępniane przez css3, ułatwiają projektowanie i tworzenie umów SPA.

Wszystkie przykładowe kod i fragmenty kodu znajdują się w zestawie szkoleniowym Web Camps dostępnym pod adresem https://aka.ms/webcamps-training-kit.

Omówienie

Cele

W tym praktycznym laboratorium dowiesz się, jak wykonywać następujące działania:

  • Tworzenie usługi internetowego interfejsu API ASP.NET do wysyłania i odbierania danych JSON
  • Tworzenie dynamicznego interfejsu użytkownika przy użyciu platformy AngularJS
  • Ulepszanie środowiska interfejsu użytkownika za pomocą przekształceń CSS3

Wymagania wstępne

Do ukończenia tego laboratorium praktycznego wymagane jest wykonanie następujących czynności:

Konfigurowanie

Aby uruchomić ćwiczenia w tym praktycznym laboratorium, należy najpierw skonfigurować środowisko.

  1. Otwórz Eksploratora Windows i przejdź do folderu source laboratorium.
  2. Kliknij prawym przyciskiem myszy plik Setup.cmd i wybierz polecenie Uruchom jako administrator , aby uruchomić proces instalacji, który skonfiguruje środowisko i zainstaluj fragmenty kodu programu Visual Studio dla tego laboratorium.
  3. Jeśli zostanie wyświetlone okno dialogowe Kontrola konta użytkownika, potwierdź akcję, aby kontynuować.

Uwaga

Przed uruchomieniem konfiguracji upewnij się, że sprawdzono wszystkie zależności dla tego laboratorium.

Używanie fragmentów kodu

W całym dokumencie laboratorium zostanie wyświetlony monit o wstawienie bloków kodu. Dla wygody większość tego kodu jest udostępniana jako Visual Studio Code fragmenty kodu, do których można uzyskać dostęp z poziomu Visual Studio 2013, aby uniknąć konieczności ręcznego dodawania go.

Uwaga

Każdemu ćwiczeniu towarzyszy rozwiązanie początkowe znajdujące się w folderze Begin ćwiczenia, które umożliwia wykonywanie poszczególnych ćwiczeń niezależnie od innych. Należy pamiętać, że w tych rozwiązaniach początkowych brakuje fragmentów kodu dodanych podczas ćwiczenia i mogą nie działać, dopóki nie ukończysz ćwiczenia. Wewnątrz kodu źródłowego ćwiczenia znajdziesz również folder End zawierający rozwiązanie programu Visual Studio z kodem, który wynika z wykonania kroków w odpowiednim ćwiczeniu. Możesz użyć tych rozwiązań jako wskazówek, jeśli potrzebujesz dodatkowej pomocy podczas pracy z tym praktycznym laboratorium.


Ćwiczenia

To praktyczne laboratorium obejmuje następujące ćwiczenia:

  1. Tworzenie internetowego interfejsu API
  2. Tworzenie interfejsu SPA

Szacowany czas ukończenia tego laboratorium: 60 minut

Uwaga

Po pierwszym uruchomieniu programu Visual Studio należy wybrać jedną ze wstępnie zdefiniowanych kolekcji ustawień. Każda wstępnie zdefiniowana kolekcja jest przeznaczona do dopasowania określonego stylu programowania i określa układy okien, zachowanie edytora, fragmenty kodu IntelliSense i opcje okna dialogowego. Procedury w tym laboratorium opisują akcje niezbędne do wykonania danego zadania w programie Visual Studio podczas korzystania z kolekcji Ogólne ustawienia programowania . W przypadku wybrania innej kolekcji ustawień dla środowiska deweloperskiego mogą wystąpić różnice w krokach, które należy wziąć pod uwagę.

Ćwiczenie 1. Tworzenie internetowego interfejsu API

Jedną z kluczowych części SPA jest warstwa usługi. Odpowiada za przetwarzanie wywołań Ajax wysyłanych przez interfejs użytkownika i zwracanie danych w odpowiedzi na to wywołanie. Pobrane dane powinny być prezentowane w formacie czytelnym dla komputera, aby można je było analizować i wykorzystywać przez klienta.

Struktura internetowego interfejsu API jest częścią stosu ASP.NET i została zaprojektowana w celu ułatwienia implementowania usług HTTP, zazwyczaj wysyłania i odbierania danych w formacie JSON lub XML za pośrednictwem interfejsu API RESTful. W tym ćwiczeniu utworzysz witrynę sieci Web do hostowania aplikacji Geek Quiz, a następnie zaimplementujesz usługę zaplecza, aby uwidocznić i utrwały dane testu przy użyciu internetowego interfejsu API ASP.NET.

Zadanie 1 — Tworzenie projektu początkowego dla geek quizu

W tym zadaniu rozpoczniesz tworzenie nowego projektu MVC ASP.NET z obsługą ASP.NET internetowego interfejsu API opartego na typie projektu One ASP.NET dostarczanym z programem Visual Studio. Jedna ASP.NET jednoczy wszystkie technologie ASP.NET i daje możliwość połączenia i dopasowania ich zgodnie z potrzebami. Następnie dodasz klasy modelu programu Entity Framework i inicjator bazy danych, aby wstawić pytania testowe.

  1. Otwórz Visual Studio Express 2013 dla sieci Web i wybierz pozycję Plik | Nowy projekt... aby rozpocząć nowe rozwiązanie.

    Tworzenie nowego projektu w

    Tworzenie nowego projektu

  2. W oknie dialogowym Nowy projekt wybierz pozycję ASP.NET aplikacja internetowa w obszarze Visual C# | Karta Sieci Web. Upewnij się, że wybrano .NET Framework 4.5, nadaj mu nazwę GeekQuiz, wybierz lokalizację i kliknij przycisk OK.

    Tworzenie nowego projektu aplikacji internetowej ASP.NET

    Tworzenie nowego projektu aplikacji internetowej ASP.NET

  3. W oknie dialogowym Nowy projekt ASP.NET wybierz szablon MVC i wybierz opcję Internetowy interfejs API . Upewnij się również, że opcja Uwierzytelnianie jest ustawiona na indywidualne konta użytkowników. Kliknij przycisk OK, aby kontynuować.

    Tworzenie nowego projektu przy użyciu szablonu MVC, w tym składników internetowego interfejsu API

    Tworzenie nowego projektu przy użyciu szablonu MVC, w tym składników internetowego interfejsu API

  4. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder Models projektu GeekQuiz i wybierz polecenie Dodaj | Istniejący element....

    Dodawanie istniejącego elementu Dodawanie

    Dodawanie istniejącego elementu

  5. W oknie dialogowym Dodawanie istniejącego elementu przejdź do folderu Source/Assets/Models i wybierz wszystkie pliki. Kliknij pozycję Dodaj.

    Dodawanie zasobów modelu Dodawanie

    Dodawanie zasobów modelu

    Uwaga

    Dodając te pliki, dodajesz model danych, kontekst bazy danych programu Entity Framework i inicjator bazy danych dla aplikacji Geek Quiz.

    Program Entity Framework (EF) to maper obiektowo-relacyjny (ORM), który umożliwia tworzenie aplikacji dostępu do danych przez programowanie za pomocą koncepcyjnego modelu aplikacji zamiast programowania bezpośrednio przy użyciu schematu magazynu relacyjnego. Więcej informacji na temat programu Entity Framework można znaleźć tutaj.

    Poniżej przedstawiono opis właśnie dodanych klas:

    • TriviaOption: reprezentuje jedną opcję skojarzona z pytaniem testowym
    • TriviaQuestion: reprezentuje pytanie quizu i uwidacznia skojarzone opcje za pomocą właściwości Options
    • TriviaAnswer: reprezentuje opcję wybraną przez użytkownika w odpowiedzi na pytanie quizu
    • TriviaContext: reprezentuje kontekst bazy danych platformy Entity Framework aplikacji Geek Quiz. Ta klasa pochodzi z obiektu DContext i uwidacznia właściwości DbSet , które reprezentują kolekcje jednostek opisanych powyżej.
    • TriviaDatabaseInitializer: implementacja inicjatora programu Entity Framework dla klasy TriviaContext , która dziedziczy z klasy CreateDatabaseIfNotExists. Domyślne zachowanie tej klasy polega na utworzeniu bazy danych tylko wtedy, gdy nie istnieje, wstawiając jednostki określone w metodzie Seed .
  6. Otwórz plik Global.asax.cs i dodaj następującą instrukcję using.

    using GeekQuiz.Models;
    
  7. Dodaj następujący kod na początku metody Application_Start , aby ustawić element TriviaDatabaseInitializer jako inicjator bazy danych.

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            System.Data.Entity.Database.SetInitializer(new TriviaDatabaseInitializer()); 
    
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
    
  8. Zmodyfikuj kontroler główny , aby ograniczyć dostęp do uwierzytelnionych użytkowników. W tym celu otwórz plik HomeController.cs w folderze Controllers i dodaj atrybut Authorize do definicji klasy HomeController .

    namespace GeekQuiz.Controllers
    {
        [Authorize]
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            ...
        }
    }
    

    Uwaga

    Filtr Autoryzacja sprawdza, czy użytkownik jest uwierzytelniony. Jeśli użytkownik nie jest uwierzytelniony, zwraca kod stanu HTTP 401 (Brak autoryzacji) bez wywoływania akcji. Filtr można zastosować globalnie na poziomie kontrolera lub na poziomie poszczególnych akcji.

  9. Teraz dostosujesz układ stron internetowych i znakowanie. W tym celu otwórz plik _Layout.cshtml w pliku Views | Folder udostępniony i zaktualizuj zawartość <elementu tytułu> , zastępując ciąg My ASP.NET Applicationquizem Geek.

    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>@ViewBag.Title - Geek Quiz</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    
    </head>
    
  10. W tym samym pliku zaktualizuj pasek nawigacyjny, usuwając linki Informacje i Kontakt oraz zmieniając nazwę linku Strona główna do odtwarzania. Ponadto zmień nazwę linku Nazwa aplikacji na Geek Quiz. Kod HTML paska nawigacyjnego powinien wyglądać podobnie do poniższego kodu.

    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Geek Quiz", "Index", "Home", null, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Play", "Index", "Home")</li>
                </ul>
                @Html.Partial("_LoginPartial")
            </div>
        </div>
    </div>
    
  11. Zaktualizuj stopkę strony układu, zastępując ciąg My ASP.NET Application testem Geek. W tym celu zastąp zawartość <elementu stopki> następującym wyróżnionym kodem.

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - Geek Quiz</p>
        </footer>
    </div>
    

Zadanie 2 — tworzenie internetowego interfejsu API TriviaController

W poprzednim zadaniu utworzono początkową strukturę aplikacji internetowej Geek Quiz. Teraz utworzysz prostą usługę internetowego interfejsu API, która współdziała z modelem danych testu i udostępnia następujące akcje:

  • GET /api/trivia: pobiera następne pytanie z listy quizów, na które ma odpowiedzieć uwierzytelniony użytkownik.
  • POST /api/trivia: przechowuje odpowiedź quizu określoną przez uwierzytelnioowanego użytkownika.

Użyjesz narzędzi do tworzenia szkieletów ASP.NET udostępnianych przez program Visual Studio, aby utworzyć punkt odniesienia dla klasy kontrolera internetowego interfejsu API.

  1. Otwórz plik WebApiConfig.cs w folderze App_Start . Ten plik definiuje konfigurację usługi internetowego interfejsu API, na przykład sposób mapowania tras na akcje kontrolera internetowego interfejsu API.

  2. Dodaj następującą instrukcję using na początku pliku.

    using Newtonsoft.Json.Serialization;
    
  3. Dodaj następujący wyróżniony kod do metody Register , aby globalnie skonfigurować formater dla danych JSON pobranych przez metody akcji internetowego interfejsu API.

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
    
            // Use camel case for JSON data.
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    
            // Web API routes
            config.MapHttpAttributeRoutes();
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
    

    Uwaga

    CamelCasePropertyNamesContractResolver automatycznie konwertuje nazwy właściwości na przypadek camel, czyli ogólną konwencję nazw właściwości w języku JavaScript.

  4. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder Controllers projektu GeekQuiz i wybierz pozycję Dodaj | Nowy element szkieletowy....

    Tworzenie nowego elementu szkieletowego Tworzenie

    Tworzenie nowego elementu szkieletowego

  5. W oknie dialogowym Dodawanie szkieletu upewnij się, że w okienku po lewej stronie wybrano pozycję Wspólny węzeł. Następnie wybierz kontroler internetowego interfejsu API 2 — pusty szablon w środkowym okienku i kliknij przycisk Dodaj.

    Wybieranie szablonu Pusty kontroler internetowego interfejsu API 2

    Wybieranie pustego szablonu kontrolera internetowego interfejsu API 2

    Uwaga

    ASP.NET tworzenie szkieletów to struktura generowania kodu dla aplikacji internetowych ASP.NET. Visual Studio 2013 zawiera wstępnie zainstalowane generatory kodu dla projektów MVC i internetowego interfejsu API. Należy użyć szkieletu w projekcie, gdy chcesz szybko dodać kod, który wchodzi w interakcje z modelami danych, aby skrócić czas wymagany do opracowania standardowych operacji danych.

    Proces tworzenia szkieletu gwarantuje również, że wszystkie wymagane zależności są zainstalowane w projekcie. Jeśli na przykład rozpoczniesz od pustego projektu ASP.NET, a następnie użyj szkieletu, aby dodać kontroler internetowego interfejsu API, wymagane pakiety NuGet i odwołania interfejsu API sieci Web zostaną automatycznie dodane do projektu.

  6. W oknie dialogowym Dodawanie kontrolera wpisz TriviaController w polu tekstowym Nazwa kontrolera i kliknij przycisk Dodaj.

    Dodawanie kontrolera Trivia

    Dodawanie kontrolera Trivia

  7. Plik TriviaController.cs jest następnie dodawany do folderu Controllers projektu GeekQuiz zawierającego pustą klasę TriviaController . Dodaj następujące instrukcje using na początku pliku.

    (Fragment kodu — AspNetWebApiSpa — Ex1 — TriviaControllerUsings)

    using System.Data.Entity;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Web.Http.Description;
    using GeekQuiz.Models;
    
  8. Dodaj następujący kod na początku klasy TriviaController , aby zdefiniować, zainicjować i usunąć wystąpienie TriviaContext w kontrolerze.

    (Fragment kodu — AspNetWebApiSpa — Ex1 — TriviaControllerContext)

    public class TriviaController : ApiController
    {
        private TriviaContext db = new TriviaContext();
    
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.db.Dispose();
            }
    
            base.Dispose(disposing);
        }
    }
    

    Uwaga

    Metoda DisposetriviaController wywołuje metodę Dispose wystąpienia TriviaContext , co gwarantuje, że wszystkie zasoby używane przez obiekt kontekstu zostaną zwolnione, gdy wystąpienie TriviaContext zostanie usunięte lub zbierze śmieci. Obejmuje to zamknięcie wszystkich Połączenia z bazą danych otwartych przez program Entity Framework.

  9. Dodaj następującą metodę pomocnika na końcu klasy TriviaController . Ta metoda pobiera następujące pytanie quizowe z bazy danych, na które ma odpowiedzieć określony użytkownik.

    (Fragment kodu — AspNetWebApiSpa — Ex1 — TriviaControllerNextQuestion)

    private async Task<TriviaQuestion> NextQuestionAsync(string userId)
    {
        var lastQuestionId = await this.db.TriviaAnswers
            .Where(a => a.UserId == userId)
            .GroupBy(a => a.QuestionId)
            .Select(g => new { QuestionId = g.Key, Count = g.Count() })
            .OrderByDescending(q => new { q.Count, QuestionId = q.QuestionId })
            .Select(q => q.QuestionId)
            .FirstOrDefaultAsync();
    
        var questionsCount = await this.db.TriviaQuestions.CountAsync();
    
        var nextQuestionId = (lastQuestionId % questionsCount) + 1;
        return await this.db.TriviaQuestions.FindAsync(CancellationToken.None, nextQuestionId);
    }
    
  10. Dodaj następującą metodę akcji Get do klasy TriviaController . Ta metoda akcji wywołuje metodę pomocnika NextQuestionAsync zdefiniowaną w poprzednim kroku, aby pobrać następne pytanie dla uwierzytelnioowanego użytkownika.

    (Fragment kodu — AspNetWebApiSpa — Ex1 — TriviaControllerGetAction)

    // GET api/Trivia
    [ResponseType(typeof(TriviaQuestion))]
    public async Task<IHttpActionResult> Get()
    {
        var userId = User.Identity.Name;
    
        TriviaQuestion nextQuestion = await this.NextQuestionAsync(userId);
    
        if (nextQuestion == null)
        {
            return this.NotFound();
        }
    
        return this.Ok(nextQuestion);
    }
    
  11. Dodaj następującą metodę pomocnika na końcu klasy TriviaController . Ta metoda przechowuje określoną odpowiedź w bazie danych i zwraca wartość logiczną wskazującą, czy odpowiedź jest poprawna.

    (Fragment kodu — AspNetWebApiSpa — Ex1 — TriviaControllerStoreAsync)

    private async Task<bool> StoreAsync(TriviaAnswer answer)
    {
        this.db.TriviaAnswers.Add(answer);
    
        await this.db.SaveChangesAsync();
        var selectedOption = await this.db.TriviaOptions.FirstOrDefaultAsync(o => o.Id == answer.OptionId
            && o.QuestionId == answer.QuestionId);
    
        return selectedOption.IsCorrect;
    }
    
  12. Dodaj następującą metodę akcji Post do klasy TriviaController . Ta metoda akcji kojarzy odpowiedź z uwierzytelnionym użytkownikiem i wywołuje metodę pomocnika StoreAsync . Następnie wysyła odpowiedź z wartością logiczną zwróconą przez metodę pomocnika.

    (Fragment kodu — AspNetWebApiSpa — Ex1 — TriviaControllerPostAction)

    // POST api/Trivia
    [ResponseType(typeof(TriviaAnswer))]
    public async Task<IHttpActionResult> Post(TriviaAnswer answer)
    {
        if (!ModelState.IsValid)
        {
            return this.BadRequest(this.ModelState);
        }
    
        answer.UserId = User.Identity.Name;
    
        var isCorrect = await this.StoreAsync(answer);
        return this.Ok<bool>(isCorrect);
    }
    
  13. Zmodyfikuj kontroler interfejsu API sieci Web, aby ograniczyć dostęp do uwierzytelnionych użytkowników, dodając atrybut Authorize do definicji klasy TriviaController .

    [Authorize]
    public class TriviaController : ApiController
    {
        ...
    }
    

Zadanie 3 — uruchamianie rozwiązania

W tym zadaniu sprawdzisz, czy usługa internetowego interfejsu API utworzona w poprzednim zadaniu działa zgodnie z oczekiwaniami. Użyjesz narzędzi deweloperskich F12 programu Internet Explorer, aby przechwycić ruch sieciowy i sprawdzić pełną odpowiedź z usługi internetowego interfejsu API.

Uwaga

Upewnij się, że program Internet Explorer jest zaznaczony w przycisku Start znajdującym się na pasku narzędzi programu Visual Studio.

Opcja programu Internet Explorer

  1. Naciśnij klawisz F5 , aby uruchomić rozwiązanie. Strona Logowanie powinna pojawić się w przeglądarce.

    Uwaga

    Po uruchomieniu aplikacji zostanie wyzwolona domyślna trasa MVC, która domyślnie jest mapowana na akcję Indeks klasy HomeController . Ponieważ HomeController jest ograniczony do uwierzytelnionych użytkowników (pamiętaj, że ta klasa została ozdobiona atrybutem Autoryzuj w ćwiczeniu 1) i nie ma jeszcze uwierzytelnionych użytkowników, aplikacja przekierowuje oryginalne żądanie na stronę logowania.

    Uruchamianie rozwiązania Uruchamianie rozwiązania

    Uruchamianie rozwiązania

  2. Kliknij przycisk Zarejestruj, aby utworzyć nowego użytkownika.

    Rejestrowanie nowego użytkownika

    Rejestrowanie nowego użytkownika

  3. Na stronie Rejestrowanie wprowadź nazwę użytkownika i hasło, a następnie kliknij przycisk Zarejestruj.

    Strona Rejestrowanie strony Rejestrowanie

    Strona rejestrowania

  4. Aplikacja rejestruje nowe konto, a użytkownik jest uwierzytelniany i przekierowywany z powrotem do strony głównej.

    Uwierzytelniony użytkownik jest

    Użytkownik jest uwierzytelniany

  5. W przeglądarce naciśnij klawisz F12 , aby otworzyć panel Narzędzia deweloperskie . Naciśnij klawisze CTRL + 4 lub kliknij ikonę Sieć , a następnie kliknij zielony przycisk strzałki, aby rozpocząć przechwytywanie ruchu sieciowego.

    Inicjowanie przechwytywania sieci web interfejsu API inicjowania

    Inicjowanie przechwytywania sieci web interfejsu API

  6. Dołącz interfejs API/trivia do adresu URL na pasku adresu przeglądarki. Teraz sprawdzisz szczegóły odpowiedzi z metody Get akcji w triviaController.

    Pobieranie kolejnych danych pytań za pośrednictwem internetowego interfejsu API

    Pobieranie następnych danych pytań za pośrednictwem internetowego interfejsu API

    Uwaga

    Po zakończeniu pobierania zostanie wyświetlony monit o wykonanie akcji z pobranym plikiem. Pozostaw otwarte okno dialogowe, aby móc watch zawartość odpowiedzi za pośrednictwem okna Narzędzia deweloperów.

  7. Teraz sprawdzisz treść odpowiedzi. Aby to zrobić, kliknij kartę Szczegóły , a następnie kliknij pozycję Treść odpowiedzi. Możesz sprawdzić, czy pobrane dane są obiektem z opcjami właściwości (czyli listą obiektów TriviaOption ), identyfikatorem i tytułem odpowiadającym klasie TriviaQuestion .

    Wyświetlanie treści odpowiedzi internetowego interfejsu API

    Wyświetlanie treści odpowiedzi internetowego interfejsu API

  8. Wstecz do programu Visual Studio i naciśnij klawisze SHIFT + F5, aby zatrzymać debugowanie.

Ćwiczenie 2. Tworzenie interfejsu SPA

W tym ćwiczeniu najpierw utworzysz część frontonu internetowego narzędzia Geek Quiz, koncentrując się na interakcji z aplikacją Single-Page przy użyciu platformy AngularJS. Następnie rozszerzysz środowisko użytkownika za pomocą css3, aby wykonać rozbudowane animacje i zapewnić wizualny efekt przełączania kontekstu podczas przechodzenia z jednego pytania do następnego.

Zadanie 1 — Tworzenie interfejsu SPA przy użyciu platformy AngularJS

W tym zadaniu za pomocą usługi AngularJS zaimplementujesz stronę klienta aplikacji Geek Quiz. AngularJS to platforma Języka JavaScript typu open source, która rozszerza aplikacje oparte na przeglądarce za pomocą funkcji mvC (Model-View-Controller ), ułatwiając programowanie i testowanie.

Rozpoczniesz od zainstalowania platformy AngularJS z poziomu konsoli menedżera pakietów programu Visual Studio. Następnie utworzysz kontroler, aby zapewnić zachowanie aplikacji Geek Quiz i widok renderowania pytań i odpowiedzi na pytania i odpowiedzi przy użyciu aparatu szablonu AngularJS.

Uwaga

Aby uzyskać więcej informacji na temat platformy AngularJS, zobacz [http://angularjs.org/](http://angularjs.org/).

  1. Otwórz Visual Studio Express 2013 for Web i otwórz rozwiązanie GeekQuiz.sln znajdujące się w folderze Source/Ex2-CreatingASPAInterface/Begin. Alternatywnie możesz kontynuować pracę z rozwiązaniem uzyskanym w poprzednim ćwiczeniu.

  2. Otwórz konsolę Menedżera pakietów z obszaru Narzędzia>Menedżer pakietów NuGet. Wpisz następujące polecenie, aby zainstalować pakiet NuGet AngularJS.Core .

    Install-Package AngularJS.Core
    
  3. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder Scripts projektu GeekQuiz i wybierz polecenie Dodaj | Nowy folder. Nazwij aplikację folderu i naciśnij klawisz Enter.

  4. Kliknij prawym przyciskiem myszy właśnie utworzony folder aplikacji i wybierz polecenie Dodaj | Plik JavaScript.

    Tworzenie nowego pliku JavaScript

    Tworzenie nowego pliku JavaScript

  5. W oknie dialogowym Określanie nazwy elementu wpisz quiz-controller w polu tekstowym Nazwa elementu i kliknij przycisk OK.

    Nazywanie nowego pliku JavaScript

    Nazywanie nowego pliku JavaScript

  6. W pliku quiz-controller.js dodaj następujący kod, aby zadeklarować i zainicjować kontroler AngularJS QuizCtrl .

    (Fragment kodu — AspNetWebApiSpa — Ex2 — AngularQuizController)

    angular.module('QuizApp', [])
        .controller('QuizCtrl', function ($scope, $http) {
            $scope.answered = false;
            $scope.title = "loading question...";
            $scope.options = [];
            $scope.correctAnswer = false;
            $scope.working = false;
    
            $scope.answer = function () {
                return $scope.correctAnswer ? 'correct' : 'incorrect';
            };
        });
    

    Uwaga

    Funkcja konstruktora kontrolera QuizCtrl oczekuje parametru do wstrzykiwania o nazwie $scope. Początkowy stan zakresu należy skonfigurować w funkcji konstruktora przez dołączenie właściwości do obiektu $scope . Właściwości zawierają model widoku i będą dostępne dla szablonu po zarejestrowaniu kontrolera.

    Kontroler QuizCtrl jest zdefiniowany wewnątrz modułu o nazwie QuizApp. Moduły to jednostki pracy, które umożliwiają podzielenie aplikacji na oddzielne składniki. Główną zaletą korzystania z modułów jest to, że kod jest łatwiejszy do zrozumienia i ułatwia testowanie jednostkowe, ponowne użycie i konserwację.

  7. Teraz dodasz zachowanie do zakresu, aby reagować na zdarzenia wyzwalane z widoku. Dodaj następujący kod na końcu kontrolera QuizCtrl , aby zdefiniować funkcję nextQuestion w obiekcie $scope .

    (Fragment kodu — AspNetWebApiSpa — Ex2 — AngularQuizControllerNextQuestion)

    .controller('QuizCtrl', function ($scope, $http) { 
        ...
    
        $scope.nextQuestion = function () {
            $scope.working = true;
            $scope.answered = false;
            $scope.title = "loading question...";
            $scope.options = [];
    
            $http.get("/api/trivia").success(function (data, status, headers, config) {
                $scope.options = data.options;
                $scope.title = data.title;
                $scope.answered = false;
                $scope.working = false;
            }).error(function (data, status, headers, config) {
                $scope.title = "Oops... something went wrong";
                $scope.working = false;
            });
        };
    };
    

    Uwaga

    Ta funkcja pobiera następne pytanie z internetowego interfejsu API trivia utworzonego w poprzednim ćwiczeniu i dołącza dane pytania do obiektu $scope .

  8. Wstaw następujący kod na końcu kontrolera QuizCtrl , aby zdefiniować funkcję sendAnswer w obiekcie $scope .

    (Fragment kodu — AspNetWebApiSpa — Ex2 — AngularQuizControllerSendAnswer)

    .controller('QuizCtrl', function ($scope, $http) { 
        ...
    
        $scope.sendAnswer = function (option) {
            $scope.working = true;
            $scope.answered = true;
    
            $http.post('/api/trivia', { 'questionId': option.questionId, 'optionId': option.id }).success(function (data, status, headers, config) {
                $scope.correctAnswer = (data === true);
                $scope.working = false;
            }).error(function (data, status, headers, config) {
                $scope.title = "Oops... something went wrong";
                $scope.working = false;
            });
        };
    };
    

    Uwaga

    Ta funkcja wysyła odpowiedź wybraną przez użytkownika do internetowego interfejsu API Trivia i przechowuje wynik — tj. jeśli odpowiedź jest poprawna lub nie — w obiekcie $scope .

    Funkcje nextQuestion i sendAnswer z powyższego kodu używają obiektu AngularJS $http w celu abstrakcji komunikacji z internetowym interfejsem API za pośrednictwem obiektu XMLHttpRequest języka JavaScript z przeglądarki. Usługa AngularJS obsługuje inną usługę, która zapewnia wyższy poziom abstrakcji w celu wykonywania operacji CRUD względem zasobu za pośrednictwem interfejsów API RESTful. Obiekt AngularJS $resource zawiera metody akcji, które zapewniają zachowania wysokiego poziomu bez konieczności interakcji z obiektem $http . Rozważ użycie obiektu $resource w scenariuszach, które wymagają modelu CRUD (aby uzyskać informacje, zobacz dokumentację $resource).

  9. Następnym krokiem jest utworzenie szablonu angularJS definiującego widok testu. Aby to zrobić, otwórz plik Index.cshtml wewnątrz pliku Views | Folder główny i zastąp zawartość następującym kodem.

    (Fragment kodu — AspNetWebApiSpa — Ex2 — GeekQuizView)

    @{
        ViewBag.Title = "Play";
    }
    
    <div id="bodyContainer" ng-app="QuizApp">
        <section id="content">
            <div class="container" >
                <div class="row">
                    <div class="flip-container text-center col-md-12" ng-controller="QuizCtrl" ng-init="nextQuestion()">
                        <div class="back" ng-class="{flip: answered, correct: correctAnswer, incorrect:!correctAnswer}">
                            <p class="lead">{{answer()}}</p>
                            <p>
                                <button class="btn btn-info btn-lg next option" ng-click="nextQuestion()" ng-disabled="working">Next Question</button>
                            </p>
                        </div>
                        <div class="front" ng-class="{flip: answered}">
                            <p class="lead">{{title}}</p>
                            <div class="row text-center">
                                <button class="btn btn-info btn-lg option" ng-repeat="option in options" ng-click="sendAnswer(option)" ng-disabled="working">{{option.title}}</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>
    
    @section scripts {
        @Scripts.Render("~/Scripts/angular.js")
        @Scripts.Render("~/Scripts/app/quiz-controller.js")
    }
    

    Uwaga

    Szablon AngularJS to specyfikacja deklaratywna, która używa informacji z modelu i kontrolera do przekształcania znaczników statycznych w dynamiczny widok, który użytkownik widzi w przeglądarce. Poniżej przedstawiono przykłady elementów i atrybutów elementów angularJS, których można użyć w szablonie:

    • Dyrektywa ng-app informuje angularJS element DOM, który reprezentuje element główny aplikacji.
    • Dyrektywa ng-controller dołącza kontroler do modelu DOM w punkcie, w którym dyrektywa jest zadeklarowana.
    • Notacja nawiasu klamrowego {{ }} określa powiązania z właściwościami zakresu zdefiniowanymi w kontrolerze.
    • Dyrektywa ng-click służy do wywoływania funkcji zdefiniowanych w zakresie w odpowiedzi na kliknięcia użytkownika.
  10. Otwórz plik Site.css w folderze Content i dodaj następujące wyróżnione style na końcu pliku, aby zapewnić wygląd i działanie widoku testu.

    (Fragment kodu — AspNetWebApiSpa — Ex2 — GeekQuizStyles)

    .validation-summary-valid {
         display: none;
    }
    
    /* Geek Quiz styles */
    .flip-container .back,
    .flip-container .front {
         border: 5px solid #00bcf2;
         padding-bottom: 30px;
         padding-top: 30px;
    }
    
    #content {
        position:relative;
        background:#fff;
        padding:50px 0 0 0;
    }
    
    .option {
         width:140px;
         margin: 5px;
    }
    
    div.correct p {
         color: green;
    }
    
    div.incorrect p {
         color: red;
    }
    
    .btn {
         border-radius: 0;
    }
    
    .flip-container div.front, .flip-container div.back.flip {
        display: block;
    }
    
    .flip-container div.front.flip, .flip-container div.back {
        display: none;
    }
    

Zadanie 2 — uruchamianie rozwiązania

W tym zadaniu wykonasz rozwiązanie przy użyciu nowego interfejsu użytkownika utworzonego za pomocą platformy AngularJS, aby odpowiedzieć na niektóre pytania testowe.

  1. Naciśnij klawisz F5 , aby uruchomić rozwiązanie.

  2. Zarejestruj nowe konto użytkownika. W tym celu wykonaj kroki rejestracji opisane w ćwiczeniu 1, zadaniu 3.

    Uwaga

    Jeśli używasz rozwiązania z poprzedniego ćwiczenia, możesz zalogować się przy użyciu utworzonego wcześniej konta użytkownika.

  3. Powinna zostać wyświetlona strona główna przedstawiająca pierwsze pytanie testu. Odpowiedz na pytanie, klikając jedną z opcji. Spowoduje to wyzwolenie zdefiniowanej wcześniej funkcji sendAnswer , która wysyła wybraną opcję do internetowego interfejsu API Trivia .

    Odpowiadanie na pytanie

    Odpowiadanie na pytanie

  4. Po kliknięciu jednego z przycisków powinna zostać wyświetlona odpowiedź. Kliknij przycisk Dalej pytanie , aby wyświetlić następujące pytanie. Spowoduje to wyzwolenie funkcji nextQuestion zdefiniowanej w kontrolerze.

    Żądanie następnego pytania z żądaniem następnego

    Żądanie następnego pytania

  5. Powinno zostać wyświetlone następne pytanie. Kontynuuj odpowiadanie na pytania dowolną liczbę razy. Po wykonaniu wszystkich pytań należy wrócić do pierwszego pytania.

    Inne pytanie Inne pytanie

    Następne pytanie

  6. Wstecz do programu Visual Studio i naciśnij klawisze SHIFT + F5, aby zatrzymać debugowanie.

Zadanie 3 — tworzenie animacji przerzucania przy użyciu css3

W tym zadaniu użyjesz właściwości CSS3 do wykonywania rozbudowanych animacji przez dodanie efektu przerzucania po udzieleniu odpowiedzi na pytanie i pobraniu następnego pytania.

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder Content projektu GeekQuiz i wybierz polecenie Dodaj | Istniejący element....

    Dodawanie istniejącego elementu do folderu Zawartość Dodawanie

    Dodawanie istniejącego elementu do folderu Zawartość

  2. W oknie dialogowym Dodawanie istniejącego elementu przejdź do folderu Source/Assets i wybierz pozycję Flip.css. Kliknij pozycję Dodaj.

    Dodawanie pliku Flip.css z zasobów

    Dodawanie pliku Flip.css z zasobów

  3. Otwórz właśnie dodany plik Flip.css i sprawdź jego zawartość.

  4. Znajdź komentarz przekształcenia przerzucania . Poniższe style, które komentują, używają perspektywy CSS i przekształceń rotateY w celu wygenerowania efektu "przerzucania karty".

    /* flip transformation */
    .flip-container div.front {
        -moz-transform: perspective(2000px) rotateY(0deg);
        -webkit-transform: perspective(2000px) rotateY(0deg);
        -o-transform: perspective(2000px) rotateY(0deg);
        transform: perspective(2000px) rotateY(0deg);
    }
    
        .flip-container div.front.flip {
            -moz-transform: perspective(2000px) rotateY(179.9deg);
            -webkit-transform: perspective(2000px) rotateY(179.9deg);
            -o-transform: perspective(2000px) rotateY(179.9deg);
            transform: perspective(2000px) rotateY(179.9deg);
        }
    
    .flip-container div.back {
        -moz-transform: perspective(2000px) rotateY(-180deg);
        -webkit-transform: perspective(2000px) rotateY(-180deg);
        -o-transform: perspective(2000px) rotateY(-180deg);
        transform: perspective(2000px) rotateY(-180deg);
    }
    
        .flip-container div.back.flip {
            -moz-transform: perspective(2000px) rotateY(0deg);
            -webkit-transform: perspective(2000px) rotateY(0deg);
            -ms-transform: perspective(2000px) rotateY(0);
            -o-transform: perspective(2000px) rotateY(0);
            transform: perspective(2000px) rotateY(0);
        }
    
  5. Zlokalizuj ukrywanie z tyłu okienka podczas przerzucania komentarza . Styl poniżej komentarza ukrywa bok tyłu twarzy, gdy są one skierowane z dala od przeglądarki, ustawiając właściwość CSS widoczności wstecznej na ukrytą.

    /* hide back of pane during flip */
    .front, .back {
        -moz-backface-visibility: hidden;
        -webkit-backface-visibility: hidden;
        backface-visibility: hidden;
    }
    
  6. Otwórz plik BundleConfig.cs w folderze App_Start i dodaj odwołanie do pliku Flip.css w pakiecie stylów "~/Content/css"

    bundles.Add(new StyleBundle("~/Content/css").Include(
        "~/Content/bootstrap.css",
        "~/Content/site.css",
        "~/Content/Flip.css"));
    
  7. Naciśnij klawisz F5 , aby uruchomić rozwiązanie i zalogować się przy użyciu poświadczeń.

  8. Odpowiedz na pytanie, klikając jedną z opcji. Zwróć uwagę na efekt przerzucania podczas przechodzenia między widokami.

    Odpowiadanie na pytanie za pomocą efektu

    Odpowiadanie na pytanie za pomocą efektu flip

  9. Kliknij przycisk Dalej pytanie , aby pobrać następujące pytanie. Efekt przerzucania powinien pojawić się ponownie.

    Pobieranie następującego pytania z efektem przerzucania Pobieranie

    Pobieranie następującego pytania za pomocą efektu przerzucania


Podsumowanie

Wykonując to praktyczne laboratorium, wiesz, jak wykonać następujące czynności:

  • Tworzenie kontrolera internetowego interfejsu API ASP.NET przy użyciu szkieletu ASP.NET
  • Implementowanie akcji Uzyskiwanie internetowego interfejsu API w celu pobrania następnego pytania quizu
  • Implementowanie akcji Post internetowego interfejsu API w celu przechowywania odpowiedzi na quiz
  • Instalowanie usługi AngularJS z poziomu konsoli menedżera pakietów programu Visual Studio
  • Implementowanie szablonów i kontrolerów platformy AngularJS
  • Używanie przejść CSS3 w celu wykonywania efektów animacji