Lab pratico: Creare un'applicazione a pagina singola con l'API Web ASP.NET e Angular.js

by Web Camps Team

Scaricare il Kit di formazione per i campi Web

Questo lab pratico illustra come creare un'applicazione a pagina singola con API Web ASP.NET e Angular.js per ASP.NET 4.x.

In questo lab pratico, potrai sfruttare queste tecnologie per implementare Geek Quiz, un sito web semplice basato sul concetto spa. Prima di tutto si implementerà il livello di servizio con API Web ASP.NET per esporre gli endpoint necessari per recuperare le domande del quiz e archiviare le risposte. Si creerà quindi un'interfaccia utente ricca e reattiva usando gli effetti di trasformazione AngularJS e CSS3.

Nelle applicazioni Web tradizionali il client (browser) avvia la comunicazione con il server richiedendo una pagina. Il server elabora quindi la richiesta e invia il codice HTML della pagina al client. Nelle interazioni successive con la pagina, ad esempio l'utente passa a un collegamento o invia un modulo con dati, una nuova richiesta viene inviata al server e il flusso viene avviato di nuovo: il server elabora la richiesta e invia una nuova pagina al browser in risposta alla nuova azione richiesta dal client.

In Single-Page Applicazioni (SPA) l'intera pagina viene caricata nel browser dopo la richiesta iniziale, ma le interazioni successive avvengono tramite richieste Ajax. Ciò significa che il browser deve aggiornare solo la parte della pagina modificata; non è necessario ricaricare l'intera pagina. L'approccio SPA riduce il tempo impiegato dall'applicazione per rispondere alle azioni dell'utente, ottenendo un'esperienza più fluida.

L'architettura di un'applicazione a pagina singola comporta determinate sfide che non sono presenti nelle applicazioni Web tradizionali. Tuttavia, tecnologie emergenti come API Web ASP.NET, framework JavaScript come AngularJS e nuove funzionalità di stile fornite da CSS3 semplificano la progettazione e la creazione di app.

Tutti i frammenti e il codice di esempio sono inclusi nel Web Camps Training Kit, disponibile all'indirizzo https://aka.ms/webcamps-training-kit.

Panoramica

Obiettivi

In questo lab pratico si apprenderà come:

  • Creare un servizio API Web ASP.NET per inviare e ricevere dati JSON
  • Creare un'interfaccia utente reattiva usando AngularJS
  • Migliorare l'esperienza dell'interfaccia utente con le trasformazioni CSS3

Prerequisiti

Per completare questo lab pratico, è necessario quanto segue:

Installazione

Per eseguire gli esercizi in questo lab pratico, è prima necessario configurare l'ambiente.

  1. Aprire Esplora risorse e passare alla cartella Origine del lab.
  2. Fare clic con il pulsante destro del mouse su Setup.cmd e scegliere Esegui come amministratore per avviare il processo di installazione che configurerà l'ambiente e installerà i frammenti di codice di Visual Studio per questo lab.
  3. Se viene visualizzata la finestra di dialogo Controllo account utente, confermare l'azione da continuare.

Nota

Assicurarsi di aver controllato tutte le dipendenze per questo lab prima di eseguire l'installazione.

Uso dei frammenti di codice

Nel documento del lab verrà richiesto di inserire blocchi di codice. Per praticità, la maggior parte di questo codice viene fornita come frammenti di codice di Visual Studio, a cui è possibile accedere dall'interno di Visual Studio 2013 per evitare di dover aggiungerlo manualmente.

Nota

Ogni esercizio è accompagnato da una soluzione iniziale che si trova nella cartella Begin dell'esercizio che consente di seguire ogni esercizio indipendentemente dagli altri. Tenere presente che i frammenti di codice aggiunti durante un esercizio non sono presenti in queste soluzioni iniziali e potrebbero non funzionare fino a quando non si è completato l'esercizio. All'interno del codice sorgente per un esercizio si troverà anche una cartella End contenente una soluzione di Visual Studio con il codice risultante dal completamento dei passaggi nell'esercizio corrispondente. È possibile usare queste soluzioni come materiale sussidiario se è necessaria ulteriore assistenza durante l'uso di questo lab pratico.


Esercizi

Questo lab pratico include gli esercizi seguenti:

  1. Creazione di un'API Web
  2. Creazione di un'interfaccia SPA

Tempo stimato per il completamento del lab: 60 minuti

Nota

Quando si avvia Visual Studio per la prima volta, è necessario selezionare una delle raccolte di impostazioni predefinite. Ogni raccolta predefinita è progettata per corrispondere a uno stile di sviluppo specifico e determina i layout delle finestre, il comportamento dell'editor, i frammenti di codice IntelliSense e le opzioni della finestra di dialogo. Le procedure in questo lab descrivono le azioni necessarie per eseguire una determinata attività in Visual Studio quando si usa la raccolta Impostazioni di sviluppo generali . Se si sceglie una raccolta di impostazioni diversa per l'ambiente di sviluppo, potrebbero esserci differenze nei passaggi da tenere in considerazione.

Esercizio 1: Creazione di un'API Web

Una delle parti chiave di un'applicazione a pagina singola è il livello di servizio. È responsabile dell'elaborazione delle chiamate Ajax inviate dall'interfaccia utente e della restituzione dei dati in risposta a tale chiamata. I dati recuperati devono essere presentati in un formato leggibile dal computer per poter essere analizzati e utilizzati dal client.

Il framework API Web fa parte dello stack di ASP.NET ed è progettato per semplificare l'implementazione dei servizi HTTP, in genere l'invio e la ricezione di dati JSON o XML tramite un'API RESTful. In questo esercizio si creerà il sito Web per ospitare l'applicazione Geek Quiz e quindi si implementerà il servizio back-end per esporre e rendere persistenti i dati del quiz usando API Web ASP.NET.

Attività 1: creazione del progetto iniziale per il quiz geek

In questa attività si inizierà a creare un nuovo progetto MVC ASP.NET con supporto per API Web ASP.NET in base al tipo di progetto One ASP.NET fornito con Visual Studio. Una ASP.NET unifica tutte le tecnologie ASP.NET e offre la possibilità di combinarle e abbinarle in base alle esigenze. Si aggiungeranno quindi le classi del modello di Entity Framework e l'inizializzatore di database per inserire le domande del quiz.

  1. Aprire Visual Studio Express 2013 per Web e selezionare File | Nuovo progetto... per avviare una nuova soluzione.

    Creazione di un nuovo progetto

    Creazione di un nuovo progetto

  2. Nella finestra di dialogo Nuovo progetto selezionare ASP.NET'applicazione Web in Visual C# | Scheda Web . Assicurarsi che sia selezionato .NET Framework 4.5 , denominarlo GeekQuiz, scegliere un percorso e fare clic su OK.

    Creazione di un nuovo progetto applicazione Web ASP.NET

    Creazione di un nuovo progetto applicazione Web ASP.NET

  3. Nella finestra di dialogo Nuovo progetto ASP.NET selezionare il modello MVC e selezionare l'opzione API Web . Assicurarsi inoltre che l'opzione Autenticazione sia impostata su Account utente singoli. Per continuare scegliere OK .

    Creazione di un nuovo progetto con il modello MVC, inclusi i componenti dell'API Web

    Creazione di un nuovo progetto con il modello MVC, inclusi i componenti dell'API Web

  4. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Models del progetto GeekQuiz e scegliere Aggiungi | Elemento esistente....

    Aggiunta di un elemento esistente Aggiunta

    Aggiunta di un elemento esistente

  5. Nella finestra di dialogo Aggiungi elemento esistente passare alla cartella Origine/Asset/Modelli e selezionare tutti i file. Scegliere Aggiungi.

    Aggiunta degli asset del modello Aggiunta

    Aggiunta degli asset del modello

    Nota

    Aggiungendo questi file, si aggiunge il modello di dati, il contesto del database di Entity Framework e l'inizializzatore di database per l'applicazione Geek Quiz.

    Entity Framework (EF) è un mapper relazionale a oggetti (ORM) che consente di creare applicazioni di accesso ai dati programmando con un modello applicativo concettuale anziché programmare direttamente usando uno schema di archiviazione relazionale. Altre informazioni su Entity Framework sono disponibili qui.

    Di seguito è riportata una descrizione delle classi appena aggiunte:

    • TriviaOption: rappresenta una singola opzione associata a una domanda di quiz
    • TriviaQuestion: rappresenta una domanda del quiz ed espone le opzioni associate tramite la proprietà Options
    • TriviaAnswer: rappresenta l'opzione selezionata dall'utente in risposta a una domanda di quiz
    • TriviaContext: rappresenta il contesto del database di Entity Framework dell'applicazione Geek Quiz. Questa classe deriva da DContext ed espone le proprietà DbSet che rappresentano raccolte delle entità descritte in precedenza.
    • TriviaDatabaseInitializer: implementazione dell'inizializzatore di Entity Framework per la classe TriviaContext che eredita da CreateDatabaseIfNotExists. Il comportamento predefinito di questa classe consiste nel creare il database solo se non esiste, inserendo le entità specificate nel metodo Seed .
  6. Aprire il file Global.asax.cs e aggiungere l'istruzione using seguente.

    using GeekQuiz.Models;
    
  7. Aggiungere il codice seguente all'inizio del metodo Application_Start per impostare TriviaDatabaseInitializer come inizializzatore di database.

    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. Modificare il controller Home per limitare l'accesso agli utenti autenticati. A tale scopo, aprire il file HomeController.cs all'interno della cartella Controllers e aggiungere l'attributo Authorize alla definizione della classe HomeController .

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

    Nota

    Il filtro Autorizza verifica se l'utente è autenticato. Se l'utente non è autenticato, restituisce il codice di stato HTTP 401 (non autorizzato) senza richiamare l'azione. È possibile applicare il filtro a livello globale, a livello di controller o a livello di singole azioni.

  9. Ora si personalizza il layout delle pagine Web e la personalizzazione. A tale scopo, aprire il file _Layout.cshtml all'interno delle visualizzazioni | Cartella condivisa e aggiornare il contenuto dell'elemento <titolo> sostituendo My ASP.NET Application con Geek Quiz.

    <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. Nello stesso file aggiornare la barra di spostamento rimuovendo i collegamenti Informazioni e contatti e ridenominando il collegamento Home a Play. Inoltre, rinominare il collegamento Nome applicazione a Geek Quiz. Il codice HTML per la barra di spostamento dovrebbe essere simile al codice seguente.

    <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. Aggiornare il piè di pagina del layout sostituendo Il mio ASP.NET applicazione con Geek Quiz. A tale scopo, sostituire il contenuto dell'elemento <piè di pagina> con il codice evidenziato seguente.

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

Attività 2 - Creazione dell'API Web TriviaController

Nell'attività precedente è stata creata la struttura iniziale dell'applicazione Web Geek Quiz. Verrà ora creato un semplice servizio API Web che interagisce con il modello di dati del quiz ed espone le azioni seguenti:

  • GET /api/trivia: recupera la domanda successiva dall'elenco dei quiz da rispondere all'utente autenticato.
  • POST /api/trivia: archivia la risposta al quiz specificata dall'utente autenticato.

Si useranno gli strumenti di ASP.NET Scaffolding forniti da Visual Studio per creare la baseline per la classe controller API Web.

  1. Aprire il file WebApiConfig.cs all'interno della cartella App_Start . Questo file definisce la configurazione del servizio API Web, ad esempio le route mappate alle azioni del controller API Web.

  2. Aggiungere l'istruzione using seguente all'inizio del file.

    using Newtonsoft.Json.Serialization;
    
  3. Aggiungere il codice evidenziato seguente al metodo Register per configurare a livello globale il formattatore per i dati JSON recuperati dai metodi di azione dell'API Web.

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

    Nota

    CamelCasePropertyNamesContractResolver converte automaticamente i nomi delle proprietà in case camel, ovvero la convenzione generale per i nomi delle proprietà in JavaScript.

  4. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Controller del progetto GeekQuiz e scegliere Aggiungi | Nuovo elemento Scaffolded....

    Creazione di un nuovo elemento scaffolded Creazione di un nuovo elemento scaffolded

    Creazione di un nuovo elemento scaffolded

  5. Nella finestra di dialogo Aggiungi Scaffold assicurarsi che il nodo Common sia selezionato nel riquadro sinistro. Selezionare quindi il modello Web API 2 Controller - Vuoto nel riquadro centrale e fare clic su Aggiungi.

    Selezione del modello vuoto dell'API Web 2 Controller

    Selezione del modello vuoto dell'API Web 2

    Nota

    ASP.NET Scaffolding è un framework di generazione di codice per applicazioni Web ASP.NET. Visual Studio 2013 include generatori di codice preinstallati per progetti MVC e API Web. È consigliabile usare scaffolding nel progetto quando si vuole aggiungere rapidamente codice che interagisce con i modelli di dati per ridurre il tempo necessario per sviluppare operazioni di dati standard.

    Il processo di scaffolding garantisce anche l'installazione di tutte le dipendenze necessarie nel progetto. Ad esempio, se si inizia con un progetto di ASP.NET vuoto e quindi si usa scaffolding per aggiungere un controller API Web, i pacchetti e i riferimenti dell'API Web necessari vengono aggiunti automaticamente al progetto.

  6. Nella finestra di dialogo Aggiungi controller digitare TriviaController nella casella di testo Nome controller e fare clic su Aggiungi.

    Aggiunta del controller di trivia aggiungendo il controller di

    Aggiunta del controller trivia

  7. Il file TriviaController.cs viene quindi aggiunto alla cartella Controller del progetto GeekQuiz contenente una classe TriviaController vuota. Aggiungere le istruzioni using seguenti all'inizio del file.

    (Frammento di codice - AspNetWebApiSpa - Ex1 - TriviaControllerUsings)

    using System.Data.Entity;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Web.Http.Description;
    using GeekQuiz.Models;
    
  8. Aggiungere il codice seguente all'inizio della classe TriviaController per definire, inizializzare e eliminare l'istanza TriviaContext nel controller.

    (Frammento di codice - 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);
        }
    }
    

    Nota

    Il metodo Dispose di TriviaControllerrichiama il metodoDispose dell'istanza TriviaContext, che garantisce che tutte le risorse usate dall'oggetto contesto vengano rilasciate quando l'istanza TriviaContext viene eliminata o garbage-collection. Ciò include la chiusura di tutte le connessioni alle banche dati aperte da Entity Framework.

  9. Aggiungere il metodo helper seguente alla fine della classe TriviaController . Questo metodo recupera la domanda di quiz seguente dal database da rispondere all'utente specificato.

    (Frammento di codice - 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. Aggiungere il metodo Get action seguente alla classe TriviaController . Questo metodo di azione chiama il metodo helper NextQuestionAsync definito nel passaggio precedente per recuperare la domanda successiva per l'utente autenticato.

    (Frammento di codice - 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. Aggiungere il metodo helper seguente alla fine della classe TriviaController . Questo metodo archivia la risposta specificata nel database e restituisce un valore booleano che indica se la risposta è corretta.

    (Frammento di codice - 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. Aggiungere il metodo Post action seguente alla classe TriviaController . Questo metodo di azione associa la risposta all'utente autenticato e chiama il metodo helper StoreAsync . Invia quindi una risposta con il valore booleano restituito dal metodo helper.

    (Frammento di codice - 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. Modificare il controller API Web per limitare l'accesso agli utenti autenticati aggiungendo l'attributo Authorize alla definizione della classe TriviaController .

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

Attività 3: esecuzione della soluzione

In questa attività si verificherà che il servizio API Web compilato nell'attività precedente funzioni come previsto. Si userà Internet Explorer F12 Developer Tools per acquisire il traffico di rete e controllare la risposta completa dal servizio API Web.

Nota

Assicurarsi che Internet Explorer sia selezionato nel pulsante Start nella barra degli strumenti di Visual Studio.

Opzione Internet Explorer

  1. Premere F5 per eseguire la soluzione. La pagina Log in deve essere visualizzata nel browser.

    Nota

    Quando l'applicazione viene avviata, viene attivata la route MVC predefinita, che per impostazione predefinita viene mappata all'azione Index della classe HomeController . Poiché HomeController è limitato agli utenti autenticati (tenere presente che la classe è stata decorata con l'attributo Authorize in Esercizio 1) e non è ancora stata eseguita l'autenticazione dell'utente, l'applicazione reindirizza la richiesta originale alla pagina di accesso.

    Esecuzione della soluzione Esecuzione

    Esecuzione della soluzione

  2. Fare clic su Registra per creare un nuovo utente.

    Registrazione di un nuovo utente Registrazione di un nuovo utente

    Registrazione di un nuovo utente

  3. Nella pagina Registra immettere un nome utente e una password e quindi fare clic su Registra.

    Registrare la pagina

    Pagina Di registrazione

  4. L'applicazione registra il nuovo account e l'utente viene autenticato e reindirizzato alla home page.

    L'utente è autenticato dall'utente

    L'utente è autenticato

  5. Nel browser premere F12 per aprire il pannello Strumenti di sviluppo . Premere CTRL + 4 o fare clic sull'icona Rete e quindi fare clic sul pulsante freccia verde per iniziare a acquisire il traffico di rete.

    Avvio dell'acquisizione di rete API Web Avvio

    Avvio dell'acquisizione di rete API Web

  6. Aggiungere api/trivia all'URL nella barra degli indirizzi del browser. Si esamineranno ora i dettagli della risposta dal metodo Get action in TriviaController.

    Recupero dei dati della domanda successiva tramite l'API Web Recupero dei dati della domanda successiva tramite l'API Web

    Recupero dei dati della domanda successiva tramite l'API Web

    Nota

    Al termine del download, verrà richiesto di eseguire un'azione con il file scaricato. Lasciare aperta la finestra di dialogo per poter watch il contenuto della risposta tramite la finestra Strumento sviluppatori.

  7. Ora si esaminerà il corpo della risposta. A tale scopo, fare clic sulla scheda Dettagli e quindi su Corpo risposta. È possibile verificare che i dati scaricati siano un oggetto con le opzioni delle proprietà (ovvero un elenco di oggetti TriviaOption ), id e titolo che corrispondono alla classe TriviaQuestion .

    Visualizzazione del corpo della risposta api Web Che visualizza il corpo

    Visualizzazione del corpo della risposta api Web

  8. Indietro a Visual Studio e premere MAIUSC + F5 per arrestare il debug.

Esercizio 2: Creazione dell'interfaccia SPA

In questo esercizio si creerà prima la parte front-end Web di Geek Quiz, concentrandosi sull'interazione dell'applicazione Single-Page usando AngularJS. Si migliorerà quindi l'esperienza utente con CSS3 per eseguire animazioni avanzate e fornire un effetto visivo del cambio di contesto durante la transizione da una domanda alla successiva.

Attività 1 - Creazione dell'interfaccia SPA con AngularJS

In questa attività si userà AngularJS per implementare il lato client dell'applicazione Geek Quiz. AngularJS è un framework JavaScript open source che aumenta le applicazioni basate su browser con funzionalità Model-View-Controller (MVC), semplificando sia lo sviluppo che il test.

Si inizierà installando AngularJS dalla console di Gestione pacchetti di Visual Studio. Verrà quindi creato il controller per fornire il comportamento dell'app Geek Quiz e la visualizzazione per eseguire il rendering delle domande e delle risposte del quiz usando il motore di modelli AngularJS.

Nota

Per altre informazioni su AngularJS, vedere [http://angularjs.org/](http://angularjs.org/).

  1. Aprire Visual Studio Express 2013 per Web e aprire la soluzione GeekQuiz.sln disponibile nella cartella Source/Ex2-CreatingASPAInterface/Begin. In alternativa, è possibile continuare con la soluzione ottenuta nell'esercizio precedente.

  2. Aprire la console di Gestione pacchetti da Strumenti>Gestione pacchetti NuGet. Digitare il comando seguente per installare il pacchetto NuGet AngularJS.Core .

    Install-Package AngularJS.Core
    
  3. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Script del progetto GeekQuiz e scegliere Aggiungi | Nuova cartella. Assegnare un nome all'app per la cartella e premere INVIO.

  4. Fare clic con il pulsante destro del mouse sulla cartella dell'app appena creata e selezionare Aggiungi | File JavaScript.

    Creazione di un nuovo file JavaScript

    Creazione di un nuovo file JavaScript

  5. Nella finestra di dialogo Specifica nome per elemento digitare quiz-controller nella casella di testo Nome elemento e fare clic su OK.

    Denominazione del nuovo file JavaScript

    Denominazione del nuovo file JavaScript

  6. Nel file quiz-controller.js aggiungere il codice seguente per dichiarare e inizializzare il controller AngularJS QuizCtrl .

    (Frammento di codice - 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';
            };
        });
    

    Nota

    La funzione del costruttore del controller QuizCtrl prevede un parametro iniettabile denominato $scope. Lo stato iniziale dell'ambito deve essere configurato nella funzione del costruttore associando le proprietà all'oggetto $scope . Le proprietà contengono il modello di visualizzazione e saranno accessibili al modello quando il controller è registrato.

    Il controller QuizCtrl viene definito all'interno di un modulo denominato QuizApp. I moduli sono unità di lavoro che consentono di suddividere l'applicazione in componenti separati. I principali vantaggi dell'uso dei moduli è che il codice è più facile da comprendere e facilitare unit test, riutilizzabilità e gestibilità.

  7. Verrà ora aggiunto il comportamento all'ambito per reagire agli eventi attivati dalla visualizzazione. Aggiungere il codice seguente alla fine del controller QuizCtrl per definire la funzione nextQuestion nell'oggetto $scope .

    (Frammento di codice - 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;
            });
        };
    };
    

    Nota

    Questa funzione recupera la domanda successiva dall'API Web Trivia creata nell'esercizio precedente e collega i dati della domanda all'oggetto $scope .

  8. Inserire il codice seguente alla fine del controller QuizCtrl per definire la funzione sendAnswer nell'oggetto $scope .

    (Frammento di codice - 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;
            });
        };
    };
    

    Nota

    Questa funzione invia la risposta selezionata dall'utente all'API Web Trivia e archivia il risultato, ovvero se la risposta è corretta o meno, nell'oggetto $scope .

    Le funzioni nextQuestion e sendAnswer precedenti usano l'oggetto AngularJS $http per astrazione della comunicazione con l'API Web tramite l'oggetto XMLHttpRequest JavaScript dal browser. AngularJS supporta un altro servizio che porta un livello superiore di astrazione per eseguire operazioni CRUD su una risorsa tramite API RESTful. L'oggetto AngularJS $resource include metodi di azione che forniscono comportamenti di alto livello senza la necessità di interagire con l'oggetto $http . È consigliabile usare l'oggetto $resource negli scenari che richiedono il modello CRUD (pere informazioni, vedere la documentazione di $resource).

  9. Il passaggio successivo consiste nel creare il modello AngularJS che definisce la visualizzazione per il quiz. A tale scopo, aprire il file Index.cshtml all'interno delle visualizzazioni | Home folder e sostituire il contenuto con il codice seguente.

    (Frammento di codice - 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")
    }
    

    Nota

    Il modello AngularJS è una specifica dichiarativa che usa informazioni dal modello e dal controller per trasformare il markup statico nella visualizzazione dinamica visualizzata dall'utente nel browser. Di seguito sono riportati esempi di elementi angularJS e attributi di elemento che possono essere usati in un modello:

    • La direttiva ng-app indica a AngularJS l'elemento DOM che rappresenta l'elemento radice dell'applicazione.
    • La direttiva ng-controller collega un controller al DOM nel punto in cui viene dichiarata la direttiva.
    • La notazione parentesi graffe {{ }} indica le associazioni alle proprietà dell'ambito definite nel controller.
    • La direttiva ng-click viene usata per richiamare le funzioni definite nell'ambito in risposta ai clic dell'utente.
  10. Aprire il file Site.css all'interno della cartella Contenuto e aggiungere gli stili evidenziati seguenti alla fine del file per fornire un aspetto e sentire per la visualizzazione del quiz.

    (Frammento di codice - 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;
    }
    

Attività 2: esecuzione della soluzione

In questa attività si eseguirà la soluzione usando la nuova interfaccia utente creata con AngularJS per rispondere a alcune delle domande del quiz.

  1. Premere F5 per eseguire la soluzione.

  2. Registrare un nuovo account utente. A tale scopo, seguire i passaggi di registrazione descritti in Esercizio 1, Attività 3.

    Nota

    Se si usa la soluzione dell'esercizio precedente, è possibile accedere con l'account utente creato prima.

  3. La home page dovrebbe essere visualizzata, che mostra la prima domanda del quiz. Rispondere alla domanda facendo clic su una delle opzioni. Verrà attivata la funzione sendAnswer definita in precedenza, che invia l'opzione selezionata all'API Web Trivia .

    Risposta a una domanda che risponde

    Risposta a una domanda

  4. Dopo aver fatto clic su uno dei pulsanti, verrà visualizzata la risposta. Fare clic su Avanti domanda per visualizzare la domanda seguente. Verrà attivata la funzione nextQuestion definita nel controller.

    Richiesta della domanda successiva

    Richiesta della domanda successiva

  5. La domanda successiva dovrebbe essere visualizzata. Continuare a rispondere alle domande quante volte si desidera. Dopo aver completato tutte le domande che dovresti tornare alla prima domanda.

    Un'altra domanda Un'altra domanda

    Prossima domanda

  6. Indietro a Visual Studio e premere MAIUSC + F5 per arrestare il debug.

Attività 3: creazione di un'animazione flip con CSS3

In questa attività si useranno le proprietà CSS3 per eseguire animazioni avanzate aggiungendo un effetto capovolgimento quando viene risposta una domanda e quando viene recuperata la domanda successiva.

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Contenuto del progetto GeekQuiz e scegliere Aggiungi | Elemento esistente....

    Aggiunta di un elemento esistente alla cartella Contenuto Aggiunta di un elemento esistente

    Aggiunta di un elemento esistente alla cartella Contenuto

  2. Nella finestra di dialogo Aggiungi elemento esistente passare alla cartella Origine/Asset e selezionare Flip.css. Scegliere Aggiungi.

    Aggiunta del file Flip.css da Assets Aggiungendo il file Flip.css

    Aggiunta del file Flip.css da Asset

  3. Aprire il file Flip.css appena aggiunto e controllarne il contenuto.

  4. Individuare il commento della trasformazione flip . Gli stili seguenti che commento usano la prospettiva CSS e ruotano trasformazioni per generare un effetto "capovolgimento della scheda".

    /* 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. Individuare il riquadro nascosto durante il commento capovolgimento . Lo stile seguente che commento nasconde il lato posteriore dei visi quando si trovano di fronte al visualizzatore impostando la proprietà CSS di visibilità backface su nascosta.

    /* hide back of pane during flip */
    .front, .back {
        -moz-backface-visibility: hidden;
        -webkit-backface-visibility: hidden;
        backface-visibility: hidden;
    }
    
  6. Aprire il file BundleConfig.cs all'interno della cartella App_Start e aggiungere il riferimento al file Flip.css nel bundle di stile "~/Content/css"

    bundles.Add(new StyleBundle("~/Content/css").Include(
        "~/Content/bootstrap.css",
        "~/Content/site.css",
        "~/Content/Flip.css"));
    
  7. Premere F5 per eseguire la soluzione e accedere con le credenziali.

  8. Rispondere a una domanda facendo clic su una delle opzioni. Si noti l'effetto capovolgimento durante la transizione tra le visualizzazioni.

    Risposta a una domanda con l'effetto capovolgimento Risposta a una domanda

    Risposta a una domanda con l'effetto capovolgimento

  9. Fare clic su Avanti domanda per recuperare la domanda seguente. L'effetto capovolgimento dovrebbe essere visualizzato di nuovo.

    Recupero della domanda seguente con l'effetto capovolgimento Recuperando

    Recupero della domanda seguente con l'effetto capovolgimento


Riepilogo

Completando questo lab pratico si è appreso come:

  • Creare un controller di API Web ASP.NET usando ASP.NET Scaffolding
  • Implementare un'azione Ottenere un'API Web per recuperare la domanda del quiz successivo
  • Implementare un'azione Post api Web per archiviare le risposte al quiz
  • Installare AngularJS dalla console di Gestione pacchetti di Visual Studio
  • Implementare modelli e controller AngularJS
  • Usare transizioni CSS3 per eseguire effetti di animazione