Esercitazione: Inviare notifiche a utenti specifici con Hub di notifica di AzureTutorial: Send notifications to specific users by using Azure Notification Hubs

PanoramicaOverview

In questa esercitazione viene illustrato come usare Hub di notifica di Azure per inviare notifiche push a un utente specifico dell'app su un dispositivo specifico.This tutorial shows you how to use Azure Notification Hubs to send push notifications to a specific app user on a specific device. Un back-end WebAPI ASP.NET viene usato per autenticare i client.An ASP.NET WebAPI backend is used to authenticate clients. Quando il back-end autentica un utente dell'applicazione client, aggiunge automaticamente un tag per la registrazione della notifica.When the backend authenticates a client application user, it automatically adds a tag to the notification registration. Il back-end usa questo tag per inviare notifiche all'utente specifico.The backend uses this tag to send notifications to the specific user.

Nota

Il codice completo per questa esercitazione è disponibile in GitHub.The completed code for this tutorial can be found on GitHub.

In questa esercitazione vengono completati i passaggi seguenti:In this tutorial, you take the following steps:

  • Creare il progetto WebAPICreate the WebAPI project
  • Autenticare client con il back-end WebAPIAuthenticate clients to the WebAPI backend
  • Eseguire la registrazione per le notifiche tramite il back-end WebAPIRegister for notifications by using the WebAPI backend
  • Inviare notifiche dal back-end WebAPISend notifications from the WebAPI backend
  • Pubblicare il nuovo back-end WebAPIPublish the new WebAPI backend
  • Aggiornare il codice per il progetto clientUpdate the code for the client project
  • Test dell'applicazioneTest the application

prerequisitiPrerequisites

Questa esercitazione si basa sull'hub di notifica e sul progetto di Visual Studio che è stato creato nell'Esercitazione: Inviare notifiche alle app della piattaforma UWP (Universal Windows Platform) con Hub di notifica di Azure.This tutorial builds on the notification hub and Visual Studio project that you created in the Tutorial: Send notifications to Universal Windows Platform apps by using Azure Notification Hubs tutorial. Pertanto, completarla prima di avviare questa esercitazione.Therefore, complete it before starting on this tutorial.

Nota

Se si usano app per dispositivi mobili nel servizio app di Azure, vedere la versione per App per dispositivi mobili di questa esercitazione.If you are using Mobile Apps in Azure App Service as your backend service, see the Mobile Apps version of this tutorial.

 

Creare il progetto WebAPICreate the WebAPI project

Le sezioni seguenti illustrano la creazione di un nuovo back-end WebAPI ASP.NET.The following sections discuss the creation of a new ASP.NET WebAPI backend. Questo processo ha tre obiettivi principali:This process has three main purposes:

  • Autenticare i client: si aggiunge un gestore di messaggi per autenticare le richieste client e associare l'utente alla richiesta.Authenticate clients: You add a message handler to authenticate client requests and associate the user with the request.
  • Eseguire la registrazione per le notifiche usando il back-end WebAPI: si aggiunge un controller per gestire le nuove registrazioni e consentire a un dispositivo client di ricevere le notifiche.Register for notifications by using the WebAPI backend: You add a controller to handle new registrations for a client device to receive notifications. Il nome utente autenticato verrà aggiunto automaticamente alla registrazione come tag.The authenticated username is automatically added to the registration as a tag.
  • Inviare notifiche ai client: si aggiunge un controller per consentire agli utenti di attivare un push sicuro per i dispositivi e i client associati al tag.Send notifications to clients: You add a controller to provide a way for users to trigger a secure push to devices and clients associated with the tag.

Creare un nuovo back-end WebAPI ASP.NET eseguendo le azioni seguenti:Create the new ASP.NET WebAPI backend by doing the following actions:

Importante

Se si usa Visual Studio 2015 o una versione precedente, prima di procedere con l'esercitazione verificare di avere installato la versione più recente di Gestione pacchetti NuGet per Visual Studio.If you are using Visual Studio 2015 or earlier, before starting this tutorial, ensure that you have installed the latest version of NuGet Package Manager for Visual Studio.

A questo scopo, avviare Visual Studio.To check, start Visual Studio. Scegliere Estensioni e aggiornamenti dal menu Strumenti.On the Tools menu, select Extensions and Updates. Cercare Gestione pacchetti NuGet nella versione di Visual Studio e verificare che sia installata la versione più recente.Search for NuGet Package Manager in your version of Visual Studio, and make sure you have the latest version. Se la versione installata non è la più recente, disinstallarla e reinstallare Gestione pacchetti NuGet.If your version is not the latest version, uninstall it, and then reinstall the NuGet Package Manager.

Nota

Assicurarsi che sia installato Visual Studio Azure SDK per la distribuzione del sito Web.Make sure you have installed the Visual Studio Azure SDK for website deployment.>

  1. Avviare Visual Studio o Visual Studio Express.Start Visual Studio or Visual Studio Express.

  2. Selezionare Esplora server e accedere all'account Azure.Select Server Explorer, and sign in to your Azure account. Per creare le risorse del sito Web nell'account è necessario eseguire l'accesso.To create the web site resources on your account, you must be signed in.

  3. In Visual Studio fare clic con il pulsante destro del mouse sulla soluzione di Visual Studio, scegliere Aggiungi e fare clic su Nuovo progetto.In Visual Studio, right-click Visual Studio solution, point to Add, and click New Project.

  4. Espandere Visual C#, selezionare Web e fare clic su Applicazione Web ASP.NET.Expand Visual C#, select Web, and click ASP.NET Web Application.

  5. Nella casella Nome digitare AppBackend e quindi selezionare OK.In the Name box, type AppBackend, and then select OK.

    Finestra Nuovo progetto

  6. Nella finestra Nuovo progetto ASP.NET selezionare la casella di controllo API Web e quindi selezionare OK.In the New ASP.NET Project window, select the Web API check box, and then select OK.

    Finestra Nuovo progetto ASP.NET

  7. Selezionare una sottoscrizione nella finestra Configura app Web di Microsoft Azure e nell'elenco Piano di Servizio app eseguire una delle azioni seguenti:In the Configure Microsoft Azure Web App window, select a subscription and then, in the App Service plan list, do either of the following actions:

    • Selezionare un piano di servizio app creato in precedenza.Select an app service plan that you've already created.
    • Selezionare Crea un nuovo piano di servizio app e quindi creare un piano.Select Create a new app service plan, and then create one.

    Per questa esercitazione non è necessario disporre di un database.You do not need a database for this tutorial. Dopo aver selezionato il piano di servizio app, fare clic su OK per creare il progetto.After you have selected your app service plan, select OK to create the project.

    Finestra Configura app Web di Microsoft Azure

Autenticare client con il back-end WebAPIAuthenticate clients to the WebAPI backend

In questa sezione si crea una nuova classe del gestore di messaggi denominata AuthenticationTestHandler per il nuovo back-end.In this section, you create a new message-handler class named AuthenticationTestHandler for the new backend. Questa classe deriva da DelegatingHandler e viene aggiunta come gestore di messaggi per poter elaborare tutte le richieste in arrivo nel back-end.This class is derived from DelegatingHandler and added as a message handler so that it can process all requests that come into the backend.

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto AppBackend, scegliere Aggiungi e quindi selezionare Classe.In Solution Explorer, right-click the AppBackend project, select Add, and then select Class.

  2. Assegnare alla nuova classe il nome AuthenticationTestHandler.cs e fare clic su Aggiungi per generarla.Name the new class AuthenticationTestHandler.cs, and then select Add to generate the class. Questa classe autentica gli utenti tramite l'autenticazione di base.This class authenticates users by using Basic Authentication for simplicity. L'app può usare qualsiasi schema di autenticazione.Your app can use any authentication scheme.

  3. In AuthenticationTestHandler.cs aggiungere le istruzioni using seguenti:In AuthenticationTestHandler.cs, add the following using statements:

    using System.Net.Http;
    using System.Threading;
    using System.Security.Principal;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
  4. In AuthenticationTestHandler.cs sostituire la definizione di classe AuthenticationTestHandler con il codice seguente:In AuthenticationTestHandler.cs, replace the AuthenticationTestHandler class definition with the following code:

    Questo gestore autorizza la richiesta quando le tre condizioni seguenti sono vere:The handler authorizes the request when the following three conditions are true:

    • La richiesta include un'intestazione di autorizzazione.The request includes an Authorization header.
    • La richiesta usa l'autenticazione di base .The request uses basic authentication.
    • La stringa del nome utente corrisponde alla stringa della password.The user name string and the password string are the same string.

    In caso contrario, la richiesta viene rifiutata.Otherwise, the request is rejected. Non si tratta di un vero approccio di autenticazione e autorizzazione.This authentication is not a true authentication and authorization approach. È solo un esempio semplice per questa esercitazione.It is only a simple example for this tutorial.

    Se il messaggio di richiesta viene autenticato e autorizzato da AuthenticationTestHandler, l'utente dell'autenticazione di base viene associato alla richiesta corrente in HttpContext.If the request message is authenticated and authorized by AuthenticationTestHandler, the basic authentication user is attached to the current request on HttpContext. Le informazioni utente in HttpContext verranno usate da un altro controller (RegisterController) in un secondo momento per aggiungere un tag alla richiesta di registrazione per le notifiche.User information in HttpContext will be used by another controller (RegisterController) later to add a tag to the notification registration request.

    public class AuthenticationTestHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var authorizationHeader = request.Headers.GetValues("Authorization").First();
    
            if (authorizationHeader != null && authorizationHeader
                .StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase))
            {
                string authorizationUserAndPwdBase64 =
                    authorizationHeader.Substring("Basic ".Length);
                string authorizationUserAndPwd = Encoding.Default
                    .GetString(Convert.FromBase64String(authorizationUserAndPwdBase64));
                string user = authorizationUserAndPwd.Split(':')[0];
                string password = authorizationUserAndPwd.Split(':')[1];
    
                if (verifyUserAndPwd(user, password))
                {
                    // Attach the new principal object to the current HttpContext object
                    HttpContext.Current.User =
                        new GenericPrincipal(new GenericIdentity(user), new string[0]);
                    System.Threading.Thread.CurrentPrincipal =
                        System.Web.HttpContext.Current.User;
                }
                else return Unauthorized();
            }
            else return Unauthorized();
    
            return base.SendAsync(request, cancellationToken);
        }
    
        private bool verifyUserAndPwd(string user, string password)
        {
            // This is not a real authentication scheme.
            return user == password;
        }
    
        private Task<HttpResponseMessage> Unauthorized()
        {
            var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(response);
            return tsc.Task;
        }
    }
    

    Nota

    Nota sulla sicurezza: la classe AuthenticationTestHandler non fornisce un'effettiva autenticazione.Security note: The AuthenticationTestHandler class does not provide true authentication. Viene usata solo per imitare l'autenticazione di base e non è sicura.It is used only to mimic basic authentication and is not secure. È necessario implementare un meccanismo di autenticazione sicuro nelle applicazioni e nei servizi di produzione.You must implement a secure authentication mechanism in your production applications and services.

  5. Per registrare il gestore di messaggi aggiungere il codice seguente alla fine del metodo Register nella classe App_Start/WebApiConfig.cs:To register the message handler, add the following code at the end of the Register method in the App_Start/WebApiConfig.cs class:

    config.MessageHandlers.Add(new AuthenticationTestHandler());
    
  6. Salvare le modifiche.Save your changes.

Eseguire la registrazione per le notifiche tramite il back-end WebAPIRegister for notifications by using the WebAPI backend

In questa sezione si aggiunge un nuovo controller al back-end WebAPI per gestire le richieste di registrazione di un utente e un dispositivo per le notifiche tramite la libreria client per gli hub di notifica.In this section, you add a new controller to the WebAPI backend to handle requests to register a user and a device for notifications by using the client library for notification hubs. Il controller aggiunge un tag user per l'utente che è stato autenticato e collegato a HttpContext da AuthenticationTestHandler.The controller adds a user tag for the user that was authenticated and attached to HttpContext by AuthenticationTestHandler. Il tag ha il formato stringa, "username:<actual username>".The tag has the string format, "username:<actual username>".

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto AppBackend e quindi scegliere Gestisci pacchetti NuGet.In Solution Explorer, right-click the AppBackend project and then select Manage NuGet Packages.

  2. Nel riquadro sinistro selezionare Online e nella casella Cerca digitare Microsoft.Azure.NotificationHubs.In the left pane, select Online and then, in the Search box, type Microsoft.Azure.NotificationHubs.

  3. Nell'elenco dei risultati fare clic su Hub di notifica di Microsoft Azure e quindi selezionare Installa.In the results list, select Microsoft Azure Notification Hubs, and then select Install. Completare l'installazione e quindi chiudere la finestra di Gestione pacchetti NuGet.Complete the installation, and then close the NuGet Package Manager window.

    Questa azione aggiunge un riferimento ad Azure Notification Hubs SDK usando il pacchetto NuGet Microsoft.Azure.NotificationHubs.This action adds a reference to the Azure Notification Hubs SDK by using the Microsoft.Azure.Notification Hubs NuGet package.

  4. Creare un nuovo file di classe che rappresenta la connessione con l'hub di notifica usato per inviare le notifiche.Create a new class file that represents the connection with the notification hub that's used to send notifications. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Modelli, scegliere Aggiungi e quindi fare clic su Classe.In Solution Explorer, right-click the Models folder, select Add, and then select Class. Assegnare alla nuova classe il nome Notifications.cs e quindi selezionare Aggiungi per generarla.Name the new class Notifications.cs, and then select Add to generate the class.

    Finestra Aggiungi nuovo elemento

  5. In Notifications.cs aggiungere l'istruzione using seguente all'inizio del file:In Notifications.cs, add the following using statement at the top of the file:

    using Microsoft.Azure.NotificationHubs;
    
  6. Sostituire la definizione di classe Notifications con il codice seguente e sostituire i due segnaposto con la stringa di connessione (con accesso completo) per l'hub di notifica e con il nome dell'hub, disponibile nel portale di Azure:Replace the Notifications class definition with the following code, and replace the two placeholders with the connection string (with full access) for your notification hub and the hub name (available at Azure portal):

    public class Notifications
    {
        public static Notifications Instance = new Notifications();
    
        public NotificationHubClient Hub { get; set; }
    
        private Notifications() {
            Hub = NotificationHubClient.CreateClientFromConnectionString("<your hub's DefaultFullSharedAccessSignature>", 
                                                                            "<hub name>");
        }
    }
    
  7. Creare quindi un nuovo controller denominato RegisterController.Next, create a new controller named RegisterController. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Controller, scegliere Aggiungi e quindi fare clic su Controller.In Solution Explorer, right-click the Controllers folder, select Add, and then select Controller.

  8. Fare clic su Controller Web API 2 - Vuoto e selezionare Aggiungi.Select Web API 2 Controller - Empty, and then select Add.

    Finestra Aggiungi scaffolding

  9. Nella casella Nome controller digitare RegisterController per assegnare un nome alla nuova classe, quindi selezionare Aggiungi.In the Controller name box, type RegisterController to name the new class, and then select Add.

    Finestra Aggiungi controller

  10. In RegisterController.cs aggiungere le istruzioni using seguenti:In RegisterController.cs, add the following using statements:

    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.NotificationHubs.Messaging;
    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  11. Aggiungere il codice seguente all'interno della definizione di classe RegisterController .Add the following code inside the RegisterController class definition. In questo codice viene aggiunto un tag user per l'utente associato a HttpContext.In this code, you add a user tag for the user that's attached to HttpContext. L'utente è stato autenticato e associato a HttpContext dal filtro messaggi aggiunto, AuthenticationTestHandler.The user was authenticated and attached to HttpContext by the message filter that you added, AuthenticationTestHandler. È anche possibile aggiungere controlli facoltativi per verificare che l'utente disponga dei diritti per la registrazione per i tag richiesti.You can also add optional checks to verify that the user has rights to register for the requested tags.

    private NotificationHubClient hub;
    
    public RegisterController()
    {
        hub = Notifications.Instance.Hub;
    }
    
    public class DeviceRegistration
    {
        public string Platform { get; set; }
        public string Handle { get; set; }
        public string[] Tags { get; set; }
    }
    
    // POST api/register
    // This creates a registration id
    public async Task<string> Post(string handle = null)
    {
        string newRegistrationId = null;
    
        // make sure there are no existing registrations for this push handle (used for iOS and Android)
        if (handle != null)
        {
            var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100);
    
            foreach (RegistrationDescription registration in registrations)
            {
                if (newRegistrationId == null)
                {
                    newRegistrationId = registration.RegistrationId;
                }
                else
                {
                    await hub.DeleteRegistrationAsync(registration);
                }
            }
        }
    
        if (newRegistrationId == null) 
            newRegistrationId = await hub.CreateRegistrationIdAsync();
    
        return newRegistrationId;
    }
    
    // PUT api/register/5
    // This creates or updates a registration (with provided channelURI) at the specified id
    public async Task<HttpResponseMessage> Put(string id, DeviceRegistration deviceUpdate)
    {
        RegistrationDescription registration = null;
        switch (deviceUpdate.Platform)
        {
            case "mpns":
                registration = new MpnsRegistrationDescription(deviceUpdate.Handle);
                break;
            case "wns":
                registration = new WindowsRegistrationDescription(deviceUpdate.Handle);
                break;
            case "apns":
                registration = new AppleRegistrationDescription(deviceUpdate.Handle);
                break;
            case "gcm":
                registration = new GcmRegistrationDescription(deviceUpdate.Handle);
                break;
            default:
                throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
    
        registration.RegistrationId = id;
        var username = HttpContext.Current.User.Identity.Name;
    
        // add check if user is allowed to add these tags
        registration.Tags = new HashSet<string>(deviceUpdate.Tags);
        registration.Tags.Add("username:" + username);
    
        try
        {
            await hub.CreateOrUpdateRegistrationAsync(registration);
        }
        catch (MessagingException e)
        {
            ReturnGoneIfHubResponseIsGone(e);
        }
    
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    // DELETE api/register/5
    public async Task<HttpResponseMessage> Delete(string id)
    {
        await hub.DeleteRegistrationAsync(id);
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    private static void ReturnGoneIfHubResponseIsGone(MessagingException e)
    {
        var webex = e.InnerException as WebException;
        if (webex.Status == WebExceptionStatus.ProtocolError)
        {
            var response = (HttpWebResponse)webex.Response;
            if (response.StatusCode == HttpStatusCode.Gone)
                throw new HttpRequestException(HttpStatusCode.Gone.ToString());
        }
    }
    
  12. Salvare le modifiche.Save your changes.

Inviare notifiche dal back-end WebAPISend notifications from the WebAPI backend

In questa sezione si aggiunge un nuovo controller che consente ai dispositivi client di inviare una notifica.In this section, you add a new controller that exposes a way for client devices to send a notification. La notifica si basa sul tag username che usa la libreria .NET di Hub di notifica di Azure nel back-end WebAPI ASP.NET.The notification is based on the username tag that uses Azure Notification Hubs .NET Library in the ASP.NET WebAPI backend.

  1. Creare un altro nuovo controller denominato NotificationsController seguendo la stessa procedura usata per creare RegisterController nella sezione precedente.Create another new controller named NotificationsController the same way you created RegisterController in the previous section.

  2. In NotificationsController.cs aggiungere le istruzioni using seguenti:In NotificationsController.cs, add the following using statements:

    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  3. Aggiungere il metodo seguente alla classe NotificationsController:Add the following method to the NotificationsController class:

    Questo codice invia un tipo di notifica basato sul parametro pns del servizio di notifica della piattaforma (PNS).This code sends a notification type that's based on the Platform Notification Service (PNS) pns parameter. Il valore to_tag viene usato per impostare il tag username nel messaggio.The value of to_tag is used to set the username tag on the message. Questo tag deve corrispondere a un tag username di una registrazione dell'hub di notifica attiva.This tag must match a username tag of an active notification hub registration. Il messaggio di notifica viene estratto dal corpo della richiesta POST ed è formattato per il PNS di destinazione.The notification message is pulled from the body of the POST request and formatted for the target PNS.

    A seconda del servizio di notifica della piattaforma (PNS) usato dai dispositivi supportati per ricevere le notifiche, sono supportate notifiche in una serie di formati.Depending on the PNS that your supported devices use to receive notifications, the notifications are supported by a variety of formats. Nei dispositivi Windows è ad esempio possibile usare una notifica di tipo avviso popup con WNS che non è supportata direttamente da un altro PNS.For example, on Windows devices, you might use a toast notification with WNS that isn't directly supported by another PNS. In tal caso, il back-end deve formattare la notifica come notifica supportata per il PNS dei dispositivi che si intende supportare.In such an instance, your backend needs to format the notification into a supported notification for the PNS of devices you plan to support. Usare quindi l'API di invio appropriata per la classe NotificationHubClient.Then use the appropriate send API on the NotificationHubClient class.

    public async Task<HttpResponseMessage> Post(string pns, [FromBody]string message, string to_tag)
    {
        var user = HttpContext.Current.User.Identity.Name;
        string[] userTag = new string[2];
        userTag[0] = "username:" + to_tag;
        userTag[1] = "from:" + user;
    
        Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null;
        HttpStatusCode ret = HttpStatusCode.InternalServerError;
    
        switch (pns.ToLower())
        {
            case "wns":
                // Windows 8.1 / Windows Phone 8.1
                var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">" + 
                            "From " + user + ": " + message + "</text></binding></visual></toast>";
                outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag);
                break;
            case "apns":
                // iOS
                var alert = "{\"aps\":{\"alert\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, userTag);
                break;
            case "gcm":
                // Android
                var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendGcmNativeNotificationAsync(notif, userTag);
                break;
        }
    
        if (outcome != null)
        {
            if (!((outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Abandoned) ||
                (outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Unknown)))
            {
                ret = HttpStatusCode.OK;
            }
        }
    
        return Request.CreateResponse(ret);
    }
    
  4. Premere F5 per eseguire l'applicazione e verificare l'accuratezza del lavoro svolto sinora.To run the application and ensure the accuracy of your work so far, select the F5 key. L'app apre un Web browser e viene visualizzata nella home page di ASP.NET.The app opens a web browser, and it is displayed on the ASP.NET home page.

Pubblicare il nuovo back-end WebAPIPublish the new WebAPI backend

L'app verrà ora distribuita in un sito Web Azure per renderla accessibile da tutti i dispositivi.Next, you deploy the app to an Azure website to make it accessible from all devices.

  1. Fare clic con il pulsante destro del mouse sul progetto AppBackend e scegliere Pubblica.Right-click the AppBackend project, and then select Publish.

  2. Selezionare Servizio app di Microsoft Azure come destinazione di pubblicazione e quindi selezionare Pubblica.Select **Microsoft Azure App Service as your publish target, and then select **Publish. Verrà visualizzata la finestra Crea servizio app.The Create App Service window opens. Qui è possibile creare tutte le risorse di Azure necessarie per eseguire l'app Web ASP.NET in Azure.Here you can create all the necessary Azure resources to run the ASP.NET web app in Azure.

    Riquadro Servizio app di Microsoft Azure

  3. Nella finestra Crea servizio app selezionare l'account Azure.In the Create App Service window, select your Azure account. Selezionare Modifica tipo > App Web.Select Change Type > Web App. Mantenere il valore di Nome app Web predefinito e selezionare la sottoscrizione, il gruppo di risorse e il piano di servizio app.Keep the default Web App Name, and then select the Subscription, Resource Group, and App Service Plan.

  4. Selezionare Create.Select Create.

  5. Prendere nota della proprietà URL sito nella scheda Riepilogo.Make a note of the Site URL property in the Summary section. Questo URL sarà l'endpoint back-end più avanti nell'esercitazione.This URL is your back-end endpoint later in the tutorial.

  6. Selezionare Pubblica.Select Publish.

Al termine della procedura guidata, l'app Web ASP.NET viene pubblicata in Azure e aperta nel browser predefinito.After you've completed the wizard, it publishes the ASP.NET web app to Azure and then opens the app in the default browser. L'applicazione sarà visibile in Servizi app di Azure.Your application is viewable in Azure App Services.

L'URL usa il nome dell'app Web specificato in precedenza, con il formato http://<nome_app>.azurewebsites.net.The URL uses the web app name that you specified earlier, with the format http://<app_name>.azurewebsites.net.

Aggiornare il codice per il progetto clientUpdate the code for the client project

In questa sezione, si aggiornerà il codice nel progetto completato per l'Esercitazione: Inviare notifiche alle app della piattaforma UWP (Universal Windows Platform) con Hub di notifica di Azure.In this section, you update the code in the project you completed for the Tutorial: Send notifications to Universal Windows Platform apps by using Azure Notification Hubs tutorial. Il progetto deve essere già associato a Windows Store.The project should already be associated with the Windows store. Deve inoltre essere configurato per usare l'hub di notifica.It also should be configured to use your notification hub. In questa sezione si aggiungerà il codice per chiamare il nuovo back-end WebAPI e si userà tale codice per la registrazione e l'invio di notifiche.In this section, you add code to call the new WebAPI backend and use it for registering and sending notifications.

  1. In Visual Studio, aprire la soluzione creata per l'Esercitazione: Inviare notifiche alle app della piattaforma UWP (Universal Windows Platform) con Hub di notifica di Azure.In Visual Studio, open the solution you created for the Tutorial: Send notifications to Universal Windows Platform apps by using Azure Notification Hubs.
  2. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto WindowsApp e quindi scegliere Gestisci pacchetti NuGet.In Solution Explorer, right-click the WindowsApp project and then click Manage NuGet Packages.
  3. Sul lato sinistro fare clic su Online.On the left-hand side, click Online.
  4. Nella casella di ricerca digitare Client Http.In the Search box, type Http Client.
  5. Nell'elenco dei risultati fare clic su System.Net.Http, quindi su Installa.In the results list, click System.Net.Http, and click Install. Completare l'installazione.Complete the installation.
  6. Di nuovo nella casella di ricerca di NuGet digitare Json.net.Back in the NuGet Search box, type Json.net. Installare il pacchetto Newtonsoft.json, quindi chiudere la finestra di Gestione pacchetti NuGet.Install the Newtonsoft.json package, and then close the NuGet Package Manager window.
  7. In Esplora soluzioni, nel progetto WindowsApp, fare doppio clic su MainPage.xaml per aprirlo nell'editor di Visual Studio.In Solution Explorer, in the WindowsApp project, double-click MainPage.xaml to open it in the Visual Studio editor.
  8. Nel codice XML MainPage.xaml, sostituire la sezione <Grid> con il codice seguente: questo codice aggiunge una casella di testo Nome utente e Password con cui l'utente esegue l'autenticazione.In the MainPage.xaml XML code, replace the <Grid> section with the following code: This code adds a username and password textbox that the user authenticates with. Consente inoltre di aggiungere caselle di testo per il messaggio di notifica e il tag del nome utente che deve ricevere la notifica:It also adds textboxes for the notification message and the username tag that should receive the notification:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
    
        <TextBlock Grid.Row="0" Text="Notify Users" HorizontalAlignment="Center" FontSize="48"/>
    
        <StackPanel Grid.Row="1" VerticalAlignment="Center">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.ColumnSpan="3" Text="Username" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="UsernameTextBox" Grid.Row="1" Grid.ColumnSpan="3" Margin="20,0,20,0"/>
                <TextBlock Grid.Row="2" Grid.ColumnSpan="3" Text="Password" FontSize="24" Margin="20,0,20,0" />
                <PasswordBox Name="PasswordTextBox" Grid.Row="3" Grid.ColumnSpan="3" Margin="20,0,20,0"/>
    
                <Button Grid.Row="4" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center"
                            Content="1. Login and register" Click="LoginAndRegisterClick" Margin="0,0,0,20"/>
    
                <ToggleButton Name="toggleWNS" Grid.Row="5" Grid.Column="0" HorizontalAlignment="Right" Content="WNS" IsChecked="True" />
                <ToggleButton Name="toggleGCM" Grid.Row="5" Grid.Column="1" HorizontalAlignment="Center" Content="GCM" />
                <ToggleButton Name="toggleAPNS" Grid.Row="5" Grid.Column="2" HorizontalAlignment="Left" Content="APNS" />
    
                <TextBlock Grid.Row="6" Grid.ColumnSpan="3" Text="Username Tag To Send To" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="ToUserTagTextBox" Grid.Row="7" Grid.ColumnSpan="3" Margin="20,0,20,0" TextWrapping="Wrap" />
                <TextBlock Grid.Row="8" Grid.ColumnSpan="3" Text="Enter Notification Message" FontSize="24" Margin="20,0,20,0"/>
                <TextBox Name="NotificationMessageTextBox" Grid.Row="9" Grid.ColumnSpan="3" Margin="20,0,20,0" TextWrapping="Wrap" />
                <Button Grid.Row="10" Grid.ColumnSpan="3" HorizontalAlignment="Center" Content="2. Send push" Click="PushClick" Name="SendPushButton" />
            </Grid>
        </StackPanel>
    </Grid>
    
  9. In Esplora soluzioni aprire il file MainPage.xaml.cs per i progetti (Windows 8.1) e (Windows Phone 8.1).In Solution Explorer, open the MainPage.xaml.cs file for the (Windows 8.1) and (Windows Phone 8.1) projects. Aggiungere le istruzioni using seguenti all'inizio del file:Add the following using statements at the top of both files:

    using System.Net.Http;
    using Windows.Storage;
    using System.Net.Http.Headers;
    using Windows.Networking.PushNotifications;
    using Windows.UI.Popups;
    using System.Threading.Tasks;
    
  10. In MainPage.xaml.cs, per i progetti WindowsApp, aggiungere il membro seguente alla classe MainPage.In MainPage.xaml.cs for the WindowsApp project, add the following member to the MainPage class. Assicurarsi di sostituire <Enter Your Backend Endpoint> con l'endpoint back-end effettivo ottenuto in precedenza.Be sure to replace <Enter Your Backend Endpoint> with your actual backend endpoint obtained previously. Ad esempio, http://mybackend.azurewebsites.net.For example, http://mybackend.azurewebsites.net.

    private static string BACKEND_ENDPOINT = "<Enter Your Backend Endpoint>";
    
  11. Aggiungere il codice seguente alla classe MainPage in MainPage.xaml.cs per i progetti (Windows 8.1) e (Windows Phone 8.1).Add the code below to the MainPage class in MainPage.xaml.cs for the (Windows 8.1) and (Windows Phone 8.1) projects.

    Il metodo PushClick è il gestore di clic per il pulsante Send Push .The PushClick method is the click handler for the Send Push button. Chiama il back-end per attivare una notifica a tutti i dispositivi con un tag di nome utente corrispondente al parametro to_tag .It calls the backend to trigger a notification to all devices with a username tag that matches the to_tag parameter. Il messaggio di notifica viene inviato come contenuto JSON nel corpo della richiesta.The notification message is sent as JSON content in the request body.

    Il metodo LoginAndRegisterClick è il gestore di clic per il pulsante Login and register.The LoginAndRegisterClick method is the click handler for the Login and register button. Tale metodo memorizza il token di autenticazione di base (rappresenta qualsiasi token usato dallo schema di autenticazione) nell'archivio locale, quindi usa RegisterClient per la registrazione per le notifiche tramite il back-end.It stores the basic authentication token (represents any token your authentication scheme uses) in local storage, then uses RegisterClient to register for notifications using the backend.

    private async void PushClick(object sender, RoutedEventArgs e)
    {
        if (toggleWNS.IsChecked.Value)
        {
            await sendPush("wns", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
        }
        if (toggleGCM.IsChecked.Value)
        {
            await sendPush("gcm", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
        }
        if (toggleAPNS.IsChecked.Value)
        {
            await sendPush("apns", ToUserTagTextBox.Text, this.NotificationMessageTextBox.Text);
    
        }
    }
    
    private async Task sendPush(string pns, string userTag, string message)
    {
        var POST_URL = BACKEND_ENDPOINT + "/api/notifications?pns=" +
            pns + "&to_tag=" + userTag;
    
        using (var httpClient = new HttpClient())
        {
            var settings = ApplicationData.Current.LocalSettings.Values;
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string)settings["AuthenticationToken"]);
    
            try
            {
                await httpClient.PostAsync(POST_URL, new StringContent("\"" + message + "\"",
                    System.Text.Encoding.UTF8, "application/json"));
            }
            catch (Exception ex)
            {
                MessageDialog alert = new MessageDialog(ex.Message, "Failed to send " + pns + " message");
                alert.ShowAsync();
            }
        }
    }
    
    private async void LoginAndRegisterClick(object sender, RoutedEventArgs e)
    {
        SetAuthenticationTokenInLocalStorage();
    
        var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
        // The "username:<user name>" tag gets automatically added by the message handler in the backend.
        // The tag passed here can be whatever other tags you may want to use.
        try
        {
            // The device handle used is different depending on the device and PNS. 
            // Windows devices use the channel uri as the PNS handle.
            await new RegisterClient(BACKEND_ENDPOINT).RegisterAsync(channel.Uri, new string[] { "myTag" });
    
            var dialog = new MessageDialog("Registered as: " + UsernameTextBox.Text);
            dialog.Commands.Add(new UICommand("OK"));
            await dialog.ShowAsync();
            SendPushButton.IsEnabled = true;
        }
        catch (Exception ex)
        {
            MessageDialog alert = new MessageDialog(ex.Message, "Failed to register with RegisterClient");
            alert.ShowAsync();
        }
    }
    
    private void SetAuthenticationTokenInLocalStorage()
    {
        string username = UsernameTextBox.Text;
        string password = PasswordTextBox.Password;
    
        var token = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
        ApplicationData.Current.LocalSettings.Values["AuthenticationToken"] = token;
    }
    
  12. Aprire il file App.xaml.cs.Open App.xaml.cs file. Individuare la chiamata a InitNotificationsAsync() in the OnLaunched() .Find the call to InitNotificationsAsync() in the OnLaunched() event handler. Impostare come commento o eliminare la chiamata a InitNotificationsAsync().Comment out or delete the call to InitNotificationsAsync(). Il gestore del pulsante inizializzerà le registrazioni delle notifiche.The button handler initializes notification registrations.

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        //InitNotificationsAsync();
    
  13. Fare clic con il pulsante destro del mouse sul progetto WindowsApp, scegliere Aggiungi e quindi Classe.Right-click the WindowsApp project, click Add, and then click Class. Assegnare alla classe il nome RegisterClient.cs, quindi fare clic su OK per generare la classe.Name the class RegisterClient.cs, then click OK to generate the class.

    Questa classe conclude le chiamate REST necessarie per contattare il back-end dell'app allo scopo di effettuare la registrazione per le notifiche push.This class wraps the REST calls required to contact the app backend, in order to register for push notifications. Archivia inoltre in locale i registrationId creati dall'hub di notifica, come illustrato in Registrazione dal back-end dell'app.It also locally stores the registrationIds created by the Notification Hub as detailed in Registering from your app backend. Usa un token di autorizzazione memorizzato nell'archivio locale quando si fa clic sul pulsante Esegui accesso e registrazione.It uses an authorization token stored in local storage when you click the Login and register button.

  14. Aggiungere le seguenti istruzioni using all'inizio del file RegisterClient.cs:Add the following using statements at the top of the RegisterClient.cs file:

    using Windows.Storage;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using Newtonsoft.Json;
    using System.Threading.Tasks;
    using System.Linq;
    
  15. Aggiungere il codice seguente all'interno della definizione di classe RegisterClient .Add the following code inside the RegisterClient class definition.

    private string POST_URL;
    
    private class DeviceRegistration
    {
        public string Platform { get; set; }
        public string Handle { get; set; }
        public string[] Tags { get; set; }
    }
    
    public RegisterClient(string backendEndpoint)
    {
        POST_URL = backendEndpoint + "/api/register";
    }
    
    public async Task RegisterAsync(string handle, IEnumerable<string> tags)
    {
        var regId = await RetrieveRegistrationIdOrRequestNewOneAsync();
    
        var deviceRegistration = new DeviceRegistration
        {
            Platform = "wns",
            Handle = handle,
            Tags = tags.ToArray<string>()
        };
    
        var statusCode = await UpdateRegistrationAsync(regId, deviceRegistration);
    
        if (statusCode == HttpStatusCode.Gone)
        {
            // regId is expired, deleting from local storage & recreating
            var settings = ApplicationData.Current.LocalSettings.Values;
            settings.Remove("__NHRegistrationId");
            regId = await RetrieveRegistrationIdOrRequestNewOneAsync();
            statusCode = await UpdateRegistrationAsync(regId, deviceRegistration);
        }
    
        if (statusCode != HttpStatusCode.Accepted && statusCode != HttpStatusCode.OK)
        {
            // log or throw
            throw new System.Net.WebException(statusCode.ToString());
        }
    }
    
    private async Task<HttpStatusCode> UpdateRegistrationAsync(string regId, DeviceRegistration deviceRegistration)
    {
        using (var httpClient = new HttpClient())
        {
            var settings = ApplicationData.Current.LocalSettings.Values;
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string) settings["AuthenticationToken"]);
    
            var putUri = POST_URL + "/" + regId;
    
            string json = JsonConvert.SerializeObject(deviceRegistration);
                            var response = await httpClient.PutAsync(putUri, new StringContent(json, Encoding.UTF8, "application/json"));
            return response.StatusCode;
        }
    }
    
    private async Task<string> RetrieveRegistrationIdOrRequestNewOneAsync()
    {
        var settings = ApplicationData.Current.LocalSettings.Values;
        if (!settings.ContainsKey("__NHRegistrationId"))
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string)settings["AuthenticationToken"]);
    
                var response = await httpClient.PostAsync(POST_URL, new StringContent(""));
                if (response.IsSuccessStatusCode)
                {
                    string regId = await response.Content.ReadAsStringAsync();
                    regId = regId.Substring(1, regId.Length - 2);
                    settings.Add("__NHRegistrationId", regId);
                }
                else
                {
                    throw new System.Net.WebException(response.StatusCode.ToString());
                }
            }
        }
        return (string)settings["__NHRegistrationId"];
    
    }
    
  16. Salvare tutte le modifiche.Save all your changes.

Testare l'applicazioneTest the Application

  1. Avviare l'applicazione in entrambe le versioni di Windows.Launch the application on both Windows.
  2. Immettere un Nome utente e una Password come illustrato nella schermata riportata di seguito.Enter a Username and Password as shown in the screen below. È consigliabile immettere un nome utente e una password diversi dal nome utente e dalla password immessi in Windows Phone.It should differ from the user name and password you enter on Windows Phone.
  3. Fare clic su Log in and register e verificare nella relativa finestra di dialogo di avere effettuato l'accesso.Click Log in and register and verify a dialog shows that you have logged in. Questo codice abilita anche il pulsante Send Push.This code also enables the Send Push button.

  4. Quindi nel campo relativo al tag del nome utente del destinatario immettere il nome utente registrato.Then in the Recipient Username Tag field, enter the user name registered. Immettere un messaggio di notifica e fare clic su Send Push.Enter a notification message and click Send Push.
  5. Solo i dispositivi registrati con il tag del nome utente del destinatario riceveranno il messaggio di notifica.Only the devices that have registered with the matching username tag receive the notification message.

Passaggi successiviNext steps

In questa esercitazione è stato descritto come inviare notifiche push a utenti specifici che hanno tag associati alle loro registrazioni.In this tutorial, you learned how to push notifications to specific users that have tags associated with their registrations. Per informazioni sulle procedure per effettuare il push di notifiche in base alla posizione, passare all'esercitazione seguente:To learn how to push location-based notifications, advance to the following tutorial: