チュートリアル:Azure Notification Hubs を使用して特定のユーザーに通知を送信するTutorial: Send notifications to specific users by using Azure Notification Hubs

概要Overview

このチュートリアルでは、Azure Notification Hubs を使用して特定のデバイスで特定のアプリケーション ユーザーにプッシュ通知を送信する方法について説明します。This tutorial shows you how to use Azure Notification Hubs to send push notifications to a specific app user on a specific device. クライアントを認証するために ASP.NET WebAPI バックエンドが使用されます。An ASP.NET WebAPI backend is used to authenticate clients. バックエンドは、クライアント アプリケーション ユーザーを認証すると、通知の登録にタグを自動的に追加します。When the backend authenticates a client application user, it automatically adds a tag to the notification registration. バックエンドは、このタグを使用して特定のユーザーに通知を送信します。The backend uses this tag to send notifications to the specific user.

注意

このチュートリアルの完成したコードは、GitHub にあります。The completed code for this tutorial can be found on GitHub.

このチュートリアルでは、次の手順を実行します。In this tutorial, you take the following steps:

  • Web API プロジェクトを作成するCreate the WebAPI project
  • WebAPI バックエンドに対してクライアントを認証するAuthenticate clients to the WebAPI backend
  • WebAPI バックエンドを使用して通知に登録するRegister for notifications by using the WebAPI backend
  • WebAPI バックエンドから通知を送信するSend notifications from the WebAPI backend
  • 新しい WebAPI バックエンドを発行するPublish the new WebAPI backend
  • クライアント プロジェクトのコードを更新するUpdate the code for the client project
  • アプリケーションをテストするTest the application

前提条件Prerequisites

このチュートリアルは、「チュートリアル: Azure Notification Hubs を使用してユニバーサル Windows プラットフォーム アプリに通知を送信する」のチュートリアルで作成した通知ハブおよび Visual Studio プロジェクトに基づいて作成されています。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. そのため、このチュートリアルを開始する前に、それを完了してください。Therefore, complete it before starting on this tutorial.

注意

バックエンド サービスとして Azure App Service で Mobile Apps を使用している場合は、このチュートリアルの Mobile Apps バージョンに関するページをご覧ください。If you are using Mobile Apps in Azure App Service as your backend service, see the Mobile Apps version of this tutorial.

Web API プロジェクトを作成するCreate the WebAPI project

次のセクションでは、新しい ASP.NET WebAPI バックエンドの作成について説明します。The following sections discuss the creation of a new ASP.NET WebAPI backend. このプロセスには、主に次の 3 つの目的があります。This process has three main purposes:

  • クライアントの認証: クライアント要求を認証し、ユーザーを要求と関連付けるメッセージ ハンドラーを追加します。Authenticate clients: You add a message handler to authenticate client requests and associate the user with the request.
  • WebAPI バックエンドを使用した通知の登録: クライアント デバイスで通知を受信するための新しい登録を処理するコントローラーを追加します。Register for notifications by using the WebAPI backend: You add a controller to handle new registrations for a client device to receive notifications. 認証されたユーザー名はタグとして自動的に登録に追加されます。The authenticated username is automatically added to the registration as a 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.

次の操作を実行して、新しい ASP.NET WebAPI バックエンドを作成します。Create the new ASP.NET WebAPI backend by doing the following actions:

重要

Visual Studio 2015 またはそれ以前のバージョンを使用している場合は、このチュートリアルを始める前に、Visual Studio 用の最新の NuGet パッケージ マネージャーがインストールされていることを確認してください。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.

確認するには、Visual Studio を起動します。To check, start Visual Studio. [ツール] メニューの [拡張機能と更新プログラム] を選びます。On the Tools menu, select Extensions and Updates. お使いの Visual Studio に対応した NuGet パッケージ マネージャーを探し、バージョンが最新であることを確認します。Search for NuGet Package Manager in your version of Visual Studio, and make sure you have the latest version. 最新バージョンでない場合は、アンインストールして、NuGet パッケージ マネージャーを再インストールしてください。If your version is not the latest version, uninstall it, and then reinstall the NuGet Package Manager.

注意

Web サイトのデプロイ用に Visual Studio Azure SDK がインストールされていることを確認してください。Make sure you have installed the Visual Studio Azure SDK for website deployment.

  1. Visual Studio または Visual Studio Express を起動します。Start Visual Studio or Visual Studio Express.

  2. [サーバー エクスプローラー] を選択し、Azure アカウントにサインインします。Select Server Explorer, and sign in to your Azure account. アカウントの Web サイト リソースを作成するには、サインインする必要があります。To create the web site resources on your account, you must be signed in.

  3. Visual Studio で Visual Studio ソリューションを右クリックし、 [追加] をポイントして、 [新しいプロジェクト] をクリックします。In Visual Studio, right-click Visual Studio solution, point to Add, and click New Project.

  4. [Visual C#] を展開し、 [Web] を選択して [ASP.NET Web アプリケーション] をクリックします。Expand Visual C#, select Web, and click ASP.NET Web Application.

  5. [名前] ボックスに「AppBackend」と入力し、 [OK] を選択します。In the Name box, type AppBackend, and then select OK.

    [新しいプロジェクト] ウィンドウ

  6. [新しい ASP.NET プロジェクト] ウィンドウで、 [Web API] チェック ボックスをオンにし、 [OK] を選択します。In the New ASP.NET Project window, select the Web API check box, and then select OK.

    [新しい ASP.NET プロジェクト] ウィンドウ

  7. [Microsoft Azure Web App の構成] ウィンドウで、サブスクリプションを選択し、 [App Service プラン] の一覧で次のいずれかの操作を実行します。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:

    • 作成済みの App Service プランを選択します。Select an app service plan that you've already created.
    • [新しい App Service プランの作成] を選択し、App Service プランを作成します。Select Create a new app service plan, and then create one.

    このチュートリアルではデータベースは必要ありません。You do not need a database for this tutorial. App Service プランを選択したら、 [OK] を選択して、プロジェクトを作成します。After you have selected your app service plan, select OK to create the project.

    [Microsoft Azure Web App の構成] ウィンドウ

    App Service プランを構成するためのこのページが表示されない場合、チュートリアルを続行してください。If you don't see this page for configure app service plan, continue with the tutorial. これはアプリの発行時に後で構成できます。You can configure it while publishing the app later.

WebAPI バックエンドに対してクライアントを認証するAuthenticate clients to the WebAPI backend

このセクションでは、新しいバックエンドに対して AuthenticationTestHandler という名前の新しいメッセージ ハンドラー クラスを作成します。In this section, you create a new message-handler class named AuthenticationTestHandler for the new backend. このクラスは DelegatingHandler から派生し、メッセージ ハンドラーとして追加されるため、バックエンドに送信されるすべての要求を処理できます。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. ソリューション エクスプローラーで、AppBackend プロジェクトを右クリックし、 [追加][クラス] の順に選択します。In Solution Explorer, right-click the AppBackend project, select Add, and then select Class.

  2. 新しいクラスに「AuthenticationTestHandler.cs」という名前を付け、 [追加] を選択して、クラスを生成します。Name the new class AuthenticationTestHandler.cs, and then select Add to generate the class. 説明を簡単にするために、このクラスでは、基本認証を使用してユーザーを認証します。This class authenticates users by using Basic Authentication for simplicity. 実際のアプリでは、任意の認証スキームを使用できます。Your app can use any authentication scheme.

  3. AuthenticationTestHandler.cs に次の using ステートメントを追加します。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. AuthenticationTestHandler.cs で、AuthenticationTestHandler クラス定義を次のコードに置き換えます。In AuthenticationTestHandler.cs, replace the AuthenticationTestHandler class definition with the following code:

    このハンドラーは、次の 3 つの条件を満たす場合に要求を承認します。The handler authorizes the request when the following three conditions are true:

    • 要求に Authorization ヘッダーが含まれている。The request includes an Authorization header.
    • 要求に 基本 認証が使用されている。The request uses basic authentication.
    • ユーザー名の文字列とパスワードの文字列が同じである。The user name string and the password string are the same string.

    それ以外の場合、要求は拒否されます。Otherwise, the request is rejected. この認証は、認証と認可の正規のアプローチではありません。This authentication is not a true authentication and authorization approach. このチュートリアルのための単なる例にすぎません。It is only a simple example for this tutorial.

    要求メッセージが認証され、AuthenticationTestHandler によって承認される場合、基本認証ユーザーは HttpContext の現在の要求に添付されます。If the request message is authenticated and authorized by AuthenticationTestHandler, the basic authentication user is attached to the current request on HttpContext. HttpContext のユーザー情報は、後で別のコントローラー (RegisterController) で使用され、通知登録の要求にタグを追加します。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;
        }
    }
    

    注意

    セキュリティに関する注意: AuthenticationTestHandler クラスは、本当の認証を提供するわけではありません。Security note: The AuthenticationTestHandler class does not provide true authentication. 基本認証を模倣するためだけに使用されるため、安全ではありません。It is used only to mimic basic authentication and is not secure. 実稼働のアプリケーションとサービスでは、セキュリティで保護された認証メカニズムを実装する必要があります。You must implement a secure authentication mechanism in your production applications and services.

  5. メッセージ ハンドラーを登録するには、App_Start/WebApiConfig.cs クラスの Register メソッドの末尾に次のコードを追加します。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. 変更を保存します。Save your changes.

WebAPI バックエンドを使用して通知に登録するRegister for notifications by using the WebAPI backend

このセクションでは、Notification Hubs のクライアント ライブラリを使用して、通知用にユーザーとデバイスを登録する要求を処理する新しいコントローラーを WebAPI バックエンドに追加します。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. コントローラーでは、AuthenticationTestHandler で認証され、HttpContext に添付されたユーザーのユーザー タグを追加します。The controller adds a user tag for the user that was authenticated and attached to HttpContext by AuthenticationTestHandler. タグは、"username:<actual username>" という形式の文字列になります。The tag has the string format, "username:<actual username>".

  1. ソリューション エクスプローラーで AppBackend プロジェクトを右クリックし、 [NuGet パッケージの管理] を選択します。In Solution Explorer, right-click the AppBackend project and then select Manage NuGet Packages.

  2. 左側のウィンドウにある [オンライン] を選択し、 [検索] ボックスに「Microsoft.Azure.NotificationHubs」と入力します。In the left pane, select Online and then, in the Search box, type Microsoft.Azure.NotificationHubs.

  3. 結果の一覧で、 [Microsoft Azure Notification Hubs] を選択してから、 [インストール] を選択します。In the results list, select Microsoft Azure Notification Hubs, and then select Install. インストールが完了したら、NuGet パッケージ マネージャーのウィンドウを閉じます。Complete the installation, and then close the NuGet Package Manager window.

    この操作によって、Microsoft.Azure.Notification Hubs NuGet パッケージを使用して Azure Notification Hubs SDK に参照が追加されます。This action adds a reference to the Azure Notification Hubs SDK by using the Microsoft.Azure.Notification Hubs NuGet package.

  4. 通知の送信に使用する通知ハブとの接続を表す新しいクラス ファイルを作成します。Create a new class file that represents the connection with the notification hub that's used to send notifications. ソリューション エクスプローラーで、Models フォルダーを右クリックし、 [追加][クラス] の順に選択します。In Solution Explorer, right-click the Models folder, select Add, and then select Class. 新しいクラスに「Notifications.cs」という名前を付け、 [追加] を選択して、クラスを生成します。Name the new class Notifications.cs, and then select Add to generate the class.

    [新しい項目の追加] ウィンドウ

  5. Notifications.cs で、ファイルの先頭に次の using ステートメントを追加します。In Notifications.cs, add the following using statement at the top of the file:

    using Microsoft.Azure.NotificationHubs;
    
  6. Notifications クラス定義を以下のコードに置き換えます。2 つのプレースホルダーは、通知ハブに対する (フル アクセス権を持つ) 接続文字列と、ハブ名 (Azure Portalで確認できます) に置き換えます。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. 次に、RegisterController という名前の新しいコントローラーを作成します。Next, create a new controller named RegisterController. ソリューション エクスプローラーで、Controllers フォルダーを右クリックし、 [追加][コントローラー] の順に選択します。In Solution Explorer, right-click the Controllers folder, select Add, and then select Controller.

  8. [Web API 2 コントローラー - 空][追加] の順に選択します。Select Web API 2 Controller - Empty, and then select Add.

    [スキャフォールディングの追加] ウィンドウ

  9. [コントローラー名] ボックスに「RegisterController」と入力して、新しいクラスに名前を付け、 [追加] を選択します。In the Controller name box, type RegisterController to name the new class, and then select Add.

    [コントローラーの追加] ウィンドウ

  10. RegisterController.cs に次の using ステートメントを追加します。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. RegisterController クラス定義内で、次のコードを追加します。Add the following code inside the RegisterController class definition. このコードでは、HttpContext に添付されるユーザーのユーザー タグを追加します。In this code, you add a user tag for the user that's attached to HttpContext. ユーザーは認証され、追加したメッセージ フィルター AuthenticationTestHandler で HttpContext に添付されます。The user was authenticated and attached to HttpContext by the message filter that you added, AuthenticationTestHandler. また、要求されたタグを登録する権限をユーザーが持っていることを確認するコードをオプションで追加することもできます。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 "fcm":
                registration = new FcmRegistrationDescription(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. 変更を保存します。Save your changes.

WebAPI バックエンドから通知を送信するSend notifications from the WebAPI backend

このセクションでは、クライアント デバイスが通知を送信する方法を公開する新しいコントローラーを追加します。In this section, you add a new controller that exposes a way for client devices to send a notification. この通知は、ASP.NET WebAPI バックエンドの Azure Notification Hubs .NET ライブラリを使用する username タグに基づいています。The notification is based on the username tag that uses Azure Notification Hubs .NET Library in the ASP.NET WebAPI backend.

  1. 前のセクションで RegisterController を作成したときと同じ方法で、NotificationsController という別の新しいコントローラーを作成します。Create another new controller named NotificationsController the same way you created RegisterController in the previous section.

  2. NotificationsController.cs に次の using ステートメントを追加します。In NotificationsController.cs, add the following using statements:

    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  3. NotificationsController クラスに次のメソッドを追加します。Add the following method to the NotificationsController class:

    このコードでは、プラットフォーム通知サービス (PNS) の pns パラメーターに基づく通知の種類を送信します。This code sends a notification type that's based on the Platform Notification Service (PNS) pns parameter. to_tag の値はメッセージの ユーザー名 タグを設定するために使用します。The value of to_tag is used to set the username tag on the message. このタグは、アクティブな通知ハブ登録のユーザー名のタグと一致する必要があります。This tag must match a username tag of an active notification hub registration. 通知メッセージは、POST 要求の本文からプルされ、ターゲット PNS に合わせた形式に設定されます。The notification message is pulled from the body of the POST request and formatted for the target PNS.

    サポートされているデバイスで通知の受信に使用される PNS に応じて、各種形式で通知がサポートされています。Depending on the PNS that your supported devices use to receive notifications, the notifications are supported by a variety of formats. たとえば Windows デバイスの場合、別の PNS で直接はサポートされていない WNS によるトースト通知を使用することもできます。For example, on Windows devices, you might use a toast notification with WNS that isn't directly supported by another PNS. このような場合、バックエンドが、通知を、サポートを計画しているデバイスの PNS でサポートされている形式に設定する必要があります。In such an instance, your backend needs to format the notification into a supported notification for the PNS of devices you plan to support. その後、NotificationHubClient クラスで適切な送信 API を使用します。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 "fcm":
                // Android
                var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendFcmNativeNotificationAsync(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. アプリケーションを実行し、ここまでの作業に問題がないことを確認するために、F5 キーを選択します。To run the application and ensure the accuracy of your work so far, select the F5 key. アプリにより、Web ブラウザーが開き、ASP.NET ホーム ページに表示されます。The app opens a web browser, and it is displayed on the ASP.NET home page.

新しい WebAPI バックエンドを発行するPublish the new WebAPI backend

次に、このアプリを Azure の Web サイトにデプロイして、すべてのデバイスからアクセスできるようにします。Next, you deploy the app to an Azure website to make it accessible from all devices.

  1. AppBackend プロジェクトを右クリックして [発行] を選択します。Right-click the AppBackend project, and then select Publish.

  2. 発行先として [Microsoft Azure App Service] を選択し、[発行] を選択します。Select Microsoft Azure App Service as your publish target, and then select **Publish. [App Service の作成] ウィンドウが開きます。The Create App Service window opens. このウィンドウでは、Azure で ASP.NET Web アプリを実行するために必要なすべての Azure リソースを作成できます。Here you can create all the necessary Azure resources to run the ASP.NET web app in Azure.

    [Microsoft Azure App Service] タイル

  3. [App Service の作成] ウィンドウで、Azure アカウントを選択します。In the Create App Service window, select your Azure account. [変更の種類] > [Web アプリ] の順に選択します。Select Change Type > Web App. 既定の Web アプリ名をそのまま保持し、 [サブスクリプション][リソース グループ][App Service プラン] の順に選択します。Keep the default Web App Name, and then select the Subscription, Resource Group, and App Service Plan.

  4. 作成 を選択します。Select Create.

  5. [概要] セクションの [サイト URL] プロパティをメモします。Make a note of the Site URL property in the Summary section. この URL は、このチュートリアルの後半で使用する "バックエンドエンドポイント" です。This URL is your back-end endpoint later in the tutorial.

  6. [発行] を選択します。Select Publish.

ウィザードの完了後に、Azure に ASP.NET Web アプリを発行してから、既定のブラウザーでアプリを開きます。After you've completed the wizard, it publishes the ASP.NET web app to Azure and then opens the app in the default browser. アプリケーションが Azure App Services に表示されます。Your application is viewable in Azure App Services.

URL では、前に指定した Web アプリ名が http://<アプリ名>.azurewebsites.net という形式で使用されます。The URL uses the web app name that you specified earlier, with the format http://<app_name>.azurewebsites.net.

UWP クライアントのコードを更新するUpdate the code for the UWP client

このセクションでは、「チュートリアル: Azure Notification Hubs を使用してユニバーサル Windows プラットフォーム アプリに通知を送信する」のチュートリアルで完成したプロジェクト内のコードを更新します。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. このプロジェクトは、既に Windows ストアに関連付けられている必要があります。The project should already be associated with the Windows store. また、通知ハブを使用するように構成されている必要があります。It also should be configured to use your notification hub. このセクションでは、新しい WebAPI バックエンドを呼び出すコードを追加し、それを通知の登録および送信に使用します。In this section, you add code to call the new WebAPI backend and use it for registering and sending notifications.

  1. Visual Studio で、「チュートリアル: Azure Notification Hubs を使用してユニバーサル Windows プラットフォーム アプリに通知を送信する」で作成したソリューションを開きます。In Visual Studio, open the solution you created for the Tutorial: Send notifications to Universal Windows Platform apps by using Azure Notification Hubs.

  2. ソリューション エクスプローラーで、ユニバーサル Windows プラットフォーム (UWP) プロジェクトを右クリックし、[NuGet パッケージの管理] をクリックします。In Solution Explorer, right-click the Universal Windows Platform (UWP) project and then click Manage NuGet Packages.

  3. 左側で、[参照] を選択します。On the left-hand side, select Browse.

  4. [検索] ボックスに、「Http Client」と入力します。In the Search box, type Http Client.

  5. 結果の一覧で、[System.Net.Http] をクリックし、[インストール] をクリックします。In the results list, click System.Net.Http, and click Install. インストールを完了します。Complete the installation.

  6. NuGet [検索] ボックスに戻り、「Json.net」と入力します。Back in the NuGet Search box, type Json.net. Newtonsoft.json パッケージをインストールしてから、NuGet パッケージ マネージャー ウィンドウを閉じます。Install the Newtonsoft.json package, and then close the NuGet Package Manager window.

  7. ソリューション エクスプローラーで、WindowsApp プロジェクトの [MainPage.xaml] をダブルクリックして、それを Visual Studio エディターで開きます。In Solution Explorer, in the WindowsApp project, double-click MainPage.xaml to open it in the Visual Studio editor.

  8. MainPage.xaml XML コードの <Grid> セクションを次のコードで置き換えます。このコードは、ユーザーを認証するためのユーザー名とパスワードのテキスト ボックスを追加します。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. さらに、通知メッセージと通知を受け取るユーザー名タグのテキスト ボックスも追加します。It also adds text boxes 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="toggleFCM" Grid.Row="5" Grid.Column="1" HorizontalAlignment="Center" Content="FCM" />
                <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. ソリューション エクスプローラーで、(Windows 8.1) プロジェクトと (Windows Phone 8.1) プロジェクトの MainPage.xaml.cs ファイルを開きます。In Solution Explorer, open the MainPage.xaml.cs file for the (Windows 8.1) and (Windows Phone 8.1) projects. 次の using ステートメントを両方のファイルの先頭に追加します。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. WindowsApp プロジェクトの MainPage.xaml.cs で、MainPage クラスに次のメンバーを追加します。In MainPage.xaml.cs for the WindowsApp project, add the following member to the MainPage class. <Enter Your Backend Endpoint> を、前に取得した実際のバックエンド エンドポイントに必ず置き換えてください。Be sure to replace <Enter Your Backend Endpoint> with your actual backend endpoint obtained previously. たとえば、「 http://mybackend.azurewebsites.net 」のように入力します。For example, http://mybackend.azurewebsites.net.

    private static string BACKEND_ENDPOINT = "<Enter Your Backend Endpoint>";
    
  11. 次のコードを、(Windows 8.1) プロジェクトと (Windows Phone 8.1) プロジェクトの MainPage.xaml.cs 内の MainPage クラスに追加します。Add the code below to the MainPage class in MainPage.xaml.cs for the (Windows 8.1) and (Windows Phone 8.1) projects.

    PushClick メソッドは、 [プッシュを送信する] ボタン用のクリック ハンドラーです。The PushClick method is the click handler for the Send Push button. それは、バックエンドを呼び出して、ユーザー名タグが to_tag パラメーターと一致するすべてのデバイスへの通知をトリガーします。It calls the backend to trigger a notification to all devices with a username tag that matches the to_tag parameter. 通知メッセージは、要求本文で JSON コンテンツとして送信されます。The notification message is sent as JSON content in the request body.

    LoginAndRegisterClick メソッドは、[ログインして登録] ボタン用のクリック ハンドラーです。The LoginAndRegisterClick method is the click handler for the Login and register button. これは、基本的な認証トークン (認証スキームで使用される任意のトークンを表します) をローカル ストレージ内に格納してから、RegisterClient を使用してバックエンドを使用した通知に登録します。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 (toggleFCM.IsChecked.Value)
        {
            await sendPush("fcm", 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. App.xaml.cs を開いて、OnLaunched() イベント ハンドラーから InitNotificationsAsync() の呼び出しを見つけます。Open App.xaml.cs and find the call to InitNotificationsAsync() in the OnLaunched() event handler. InitNotificationsAsync()への呼び出しをコメント アウトするか削除します。Comment out or delete the call to InitNotificationsAsync(). ボタン ハンドラーは、通知の登録を初期化します。The button handler initializes notification registrations.

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        //InitNotificationsAsync();
    
  13. [WindowsApp] プロジェクトを右クリックし、[追加] をクリックしてから、[クラス] をクリックします。Right-click the WindowsApp project, click Add, and then click Class. クラスに RegisterClient.cs という名前を付け、[OK] をクリックしてクラスを生成します。Name the class RegisterClient.cs, then click OK to generate the class.

    このクラスは、プッシュ通知用に登録するために、アプリ バックエンドに接続するために必要な REST 呼び出しをラップします。This class wraps the REST calls required to contact the app backend, in order to register for push notifications. アプリ バックエンドからの登録 」で説明しているとおり、Notification Hubs によって作成された registrationIdsもローカルに格納されます。It also locally stores the registrationIds created by the Notification Hub as detailed in Registering from your app backend. [ログインして登録] ボタンをクリックすると、ローカル ストレージに格納されている承認トークンが使用されます。It uses an authorization token stored in local storage when you click the Login and register button.

  14. 次の using ステートメントを、RegisterClient.cs file ファイルの先頭に追加します。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. 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. すべての変更を保存します。Save all your changes.

アプリケーションをテストするTest the Application

  1. 両方の Windows でアプリケーションを起動します。Launch the application on both Windows.

  2. 下の画面に示すように、[ユーザー名][パスワード] を入力します。Enter a Username and Password as shown in the screen below. Windows Phone で入力するユーザー名とパスワードとは異なるユーザー名とパスワードを入力する必要があります。It should differ from the user name and password you enter on Windows Phone.

  3. [ログインして登録] をクリックし、ログインしたことを示すダイアログを確認します。Click Log in and register and verify a dialog shows that you have logged in. このコードにより、[プッシュを送信する] ボタンも有効になります。This code also enables the Send Push button.

  4. 次に、[受信ユーザー タグ] フィールドに、登録されているユーザー名を入力します。Then in the Recipient Username Tag field, enter the user name registered. 通知メッセージを入力し、 [プッシュを送信する] をクリックします。Enter a notification message and click Send Push.

  5. 一致するユーザー名タグが登録されているデバイスだけが通知メッセージを受信します。Only the devices that have registered with the matching username tag receive the notification message.

次の手順Next steps

このチュートリアルでは、タグが登録に関連付けられている特定のユーザーにプッシュ通知を送信する方法を学習しました。In this tutorial, you learned how to push notifications to specific users that have tags associated with their registrations. 場所に基づいたプッシュ通知を送信する方法を学習するには、次のチュートリアルに進んでください。To learn how to push location-based notifications, advance to the following tutorial: