Condividi tramite


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

di Web Camps Team

Scarica Kit di Formazione di Web Camps

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

In questo laboratorio pratico, potrai sfruttare queste tecnologie per implementare Geek Quiz, un sito web di trivia basato sul concetto di SPA. Per prima cosa si implementerà il livello di servizio con ASP.NET API Web 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 della 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 alcune sfide che non sono presenti nelle applicazioni Web tradizionali. Tuttavia, tecnologie emergenti come ASP.NET API Web, framework JavaScript come AngularJS e nuove funzionalità di stile fornite da CSS3 semplificano la progettazione e la creazione di applicazioni a pagina singola.

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

Informazioni generali

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 con AngularJS
  • Migliorare l'esperienza dell'interfaccia utente con le trasformazioni CSS3

Prerequisiti

Per completare questo lab pratico, è necessario quanto segue:

Setup

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

  1. Aprire Esplora risorse di Windows e passare alla cartella Origine del laboratorio.
  2. Fare clic con il pulsante destro del mouse su Setup.cmd e selezionare 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.

Annotazioni

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

Uso dei frammenti di codice

In tutto il 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 da Visual Studio 2013 per evitare di dover aggiungerlo manualmente.

Annotazioni

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 è necessario ulteriore aiuto durante l'utilizzo 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

Annotazioni

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 è lo strato 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 di ASP.NET Stack ed è progettato per semplificare l'implementazione di servizi HTTP, in genere l'invio e la ricezione di dati IN FORMATO 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 ASP.NET API Web.

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 ASP.NET API Web 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 Applicazione Web ASP.NET in Visual C# | Web. Assicurarsi che .NET Framework 4.5 sia selezionato, denominarlo GeekQuiz, scegliere un percorso e fare clic su OK.

    Creazione di un nuovo progetto applicazione Web ASP.NET Creazione

    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. Fare clic su OK per continuare.

    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 Modelli del progetto GeekQuiz e scegliere Aggiungi | Elemento esistente...

    Aggiunta di un elemento esistente Aggiunta di un elemento esistente

    Aggiunta di un elemento esistente

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

    Aggiunta degli asset del modello

    Aggiunta degli asset del modello

    Annotazioni

    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 tramite la programmazione con un modello applicativo concettuale invece di 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 del 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 del quiz
    • TriviaContext: rappresenta il contesto di 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 la seguente istruzione using.

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

    Annotazioni

    Il filtro Authorize 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. Adesso personalizzerai il layout delle pagine web e il branding. A tale scopo, aprire il file _Layout.cshtml all'interno di Views | 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 About e Contact e rinominando il collegamento Home a Play. Rinominare anche 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 della pagina di layout sostituendo My ASP.NET Application 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 quiz ed espone le azioni seguenti:

  • GET /api/trivia: recupera la domanda successiva dall'elenco di quiz a cui rispondere l'utente autenticato.
  • POST /api/trivia: archivia la risposta al quiz specificata dall'utente autenticato.

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

  1. Aprire il file WebApiConfig.cs all'interno della cartella App_Start . Questo file definisce la configurazione del servizio API Web, ad esempio il mapping delle route 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 }
            );
        }
    }
    

    Annotazioni

    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 Controllers del progetto GeekQuiz e scegliere Aggiungi | Nuovo elemento con scaffolding...

    Creazione di un nuovo elemento scaffold

    Creazione di un nuovo elemento con scaffold

  5. Nella finestra di dialogo Aggiungi impalcatura verificare che il nodo Comune sia selezionato nel riquadro sinistro. Selezionare quindi il modello Controller 2 dell'API Web - Vuoto nel riquadro centrale e fare clic su Aggiungi.

    Selezionare il modello vuoto di Web API 2 Controller

    Selezionare il modello Web API 2 Controller vuoto

    Annotazioni

    ASP.NET Scaffolding è un framework di generazione del codice per le applicazioni Web ASP.NET. Visual Studio 2013 include generatori di codice preinstallati per progetti MVC e API Web. È consigliabile usare lo scaffolding nel progetto quando si vuole aggiungere rapidamente codice che interagisce con i modelli di dati per ridurre la quantità di tempo necessaria 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 lo scaffolding per aggiungere un controller API Web, i pacchetti NuGet 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 Trivia

    Aggiunta del controller Trivia

  7. Il file TriviaController.cs viene quindi aggiunto alla cartella Controllers 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 ed 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);
        }
    }
    

    Annotazioni

    Il metodo Dispose di TriviaController richiama il metodo Dispose dell'istanza TriviaContext , che garantisce che tutte le risorse usate dall'oggetto contesto vengano rilasciate quando l'istanza TriviaContext viene eliminata o sottoposta a Garbage Collection. Ciò include la chiusura di tutte le connessioni di database aperte da Entity Framework.

  9. Aggiungere il metodo helper seguente alla fine della classe TriviaController . Questo metodo recupera la domanda del quiz seguente dal database a cui rispondere l'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 di azione Get 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 o meno.

    (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 ed esaminare la risposta completa dal servizio API Web.

Annotazioni

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

Opzione Internet Explorer

  1. Premere F5 per eseguire la soluzione. La pagina Accedi dovrebbe essere visualizzata nel browser.

    Annotazioni

    All'avvio dell'applicazione, 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 nell'esercizio 1) e non esiste ancora un utente autenticato, l'applicazione reindirizza la richiesta originale alla pagina di accesso.

    Esecuzione della soluzione

    Esecuzione della soluzione

  2. Fare clic su Registra per creare 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.

    Pagina di Registrazione Pagina di Registrazione

    Registra pagina

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

    L'utente è autenticato

    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 avviare l'acquisizione del traffico di rete.

    Avvio dell'acquisizione di rete dell'API Web

    Inizio dell'acquisizione della rete dell'API Web

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

    Recupero dei dati delle domande successive tramite

    Recupero dei dati delle domande successive tramite l'API Web

    Annotazioni

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

  7. Ora esaminerai il corpo della risposta. A tale scopo, fare clic sulla scheda Dettagli e quindi su Corpo della 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 dell'API Web

    Visualizzazione del corpo della risposta dell'API Web

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

Esercizio 2: Creazione dell'interfaccia SPA

In questo esercizio si creerà prima di tutto 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. Si creerà quindi 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.

Annotazioni

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

  1. Aprire Visual Studio Express 2013 per Il 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 Scripts 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 scegliere 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 filequiz-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';
            };
        });
    

    Annotazioni

    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 viene 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 manutenibilità.

  7. Ora aggiungerai comportamento allo scope 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;
            });
        };
    };
    

    Annotazioni

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

    Annotazioni

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

    Le funzioni nextQuestion e sendAnswer precedenti usano l'oggetto AngularJS $http per astrarre la comunicazione con l'API Web tramite l'oggetto JavaScript XMLHttpRequest dal browser. AngularJS supporta un altro servizio che offre 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 . Prendere in considerazione l'uso dell'oggetto $resource negli scenari che richiedono il modello CRUD ( per 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 di Views | 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")
    }
    

    Annotazioni

    Il modello AngularJS è una specifica dichiarativa che usa le informazioni del modello e del controller per trasformare il markup statico nella visualizzazione dinamica visualizzata dall'utente nel browser. Di seguito sono riportati esempi di attributi di elemento e elementi AngularJS 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 con parentesi graffe {{ }} indica i collegamenti alle proprietà dello scope 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 per la visualizzazione 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 ad alcune 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.

    Annotazioni

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

  3. Verrà visualizzata la home page, 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 .

    Rispondere a una domanda

    Risposta a una domanda

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

    Richiesta della prossima domanda

    Richiesta della domanda successiva

  5. Verrà visualizzata la domanda successiva. Continuare a rispondere alle domande tutte le volte desiderate. Dopo aver completato tutte le domande è necessario tornare alla prima domanda.

    Un'altra domanda Un'altra domanda

    Prossima domanda

  6. Tornare 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 di inversione 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 alla cartella Contenuto

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

    Aggiunta del file Flip.css da Assets

    Aggiunta del file Flip.css da Assets

  3. Aprire il file Flip.css appena aggiunto ed esaminarne il contenuto.

  4. Individuare il commento della trasformazione di ribaltamento. Gli stili sotto quel commento utilizzano le trasformazioni CSS perspective e rotateY per creare un effetto di ribaltamento della carta.

    /* 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 commento nascondi il retro del pannello durante il capovolgimento. Lo stile sotto quel commento nasconde la parte posteriore dei visi quando si allontanano dal visualizzatore impostando la proprietà CSS backface-visibility su hidden.

    /* 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.

    Rispondere a una domanda con l'effetto flip

    Rispondere a una domanda con l'effetto capovolgimento

  9. Fare clic su Next Question (Domanda successiva ) per recuperare la domanda seguente. L'effetto capovolgimento dovrebbe comparire nuovamente.

    Recupero della domanda seguente con l'effetto capovolgimento

    Recupero della domanda seguente con l'effetto capovolgimento


Sommario

Completando questo lab pratico si è appreso come:

  • Creare un controller API Web ASP.NET usando ASP.NET Scaffolding
  • Implementare un'azione Get di API Web per recuperare la prossima domanda del quiz
  • 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 le transizioni CSS3 per eseguire effetti di animazione