教程:使用 Azure 通知中心向 Windows 应用推送本地化通知Tutorial: Push localized notifications to Windows apps by using Azure Notification Hubs

概述Overview

本教程介绍如何将本地化通知推送到已注册到通知中心服务的移动设备。This tutorial shows you how to push localized notifications to mobile devices registered with the Notification Hubs service. 在本教程中,请更新在教程:向特定设备(通用 Windows 平台)发送通知中创建的应用程序,使之支持以下方案:In the tutorial, you update applications created in the Tutorial: Send notifications to specific devices (Universal Windows Platform) to support the following scenarios:

  • Windows 应用商店应用允许客户端设备指定一种语言并订阅不同的突发新闻类别。The Windows Store app allows client devices to specify a language, and to subscribe to different breaking news categories.
  • 后端应用使用 Azure 通知中心的标记模板功能来广播通知。The back-end app broadcasts notifications, using the tag and template features of Azure Notification Hubs.

完成本教程后,即可通过移动应用程序注册感兴趣的类别,并指定接收通知的语言。When you complete the tutorial, the mobile application lets you register for categories you are interested in, and also specify a language in which to receive the notifications. 后端应用程序可发送按语言和设备本地化的通知。The backend application sends notifications that are localized by language and device.

本教程介绍如何执行下列操作:In this tutorial, you learn how to:

  • 更新 Windows 应用,使之支持区域设置信息Update Windows app to support locale information
  • 更新后端应用,以便发送本地化通知Update back-end app to send localized notifications
  • 测试应用程序Test the app

先决条件Prerequisites

完成教程:向特定设备(通用 Windows 平台)发送通知Complete the Tutorial: Send notifications to specific devices (Universal Windows Platform).

教程:向特定设备(通用 Windows 平台)发送通知中,已开发一个使用标记订阅不同新闻类别通知的应用。In the Tutorial: Send notifications to specific devices (Universal Windows Platform), you built an app that used tags to subscribe to notifications for different news categories. 在本教程中,请使用通知中心的模板功能轻松传递本地化突发新闻通知。In this tutorial, you use the template feature of Notification Hubs to easily deliver localized breaking news notifications.

在高级别,模板是指定特定设备接收通知的格式的一种方法。At a high level, templates are a way to specify the format in which a specific device should receive a notification. 模板通过引用作为应用程序后端所发消息的一部分的属性,指定确切的负载格式。The template specifies the exact payload format by referring to properties that are part of the message sent by your app back-end. 在本教程中,后端应用程序会发送一条与区域设置无关的消息,其中包含所有支持的语言:In this tutorial, the backend application sends a locale-agnostic message containing all supported languages:

{
    "News_English": "...",
    "News_French": "...",
    "News_Mandarin": "..."
}

设备注册到引用正确属性的模板。The devices register with a template that refers to the correct property. 例如,要接收英文 toast 消息的 Windows 应用商店应用会注册以下包含任何相应标记的模板:For instance, a Windows Store app that wants to receive a toast message in English registers for the following template with any corresponding tags:

<toast>
    <visual>
    <binding template=\"ToastText01\">
        <text id=\"1\">$(News_English)</text>
    </binding>
    </visual>
</toast>

若要详细了解模板,请参阅推送模板To learn more about templates, see Push Templates.

更新 Windows 应用,使之支持区域设置信息Update Windows app to support locale information

  1. 打开为教程:向特定设备(通用 Windows 平台)发送通知创建的 Visual Studio 解决方案。Open the Visual Studio solution you created for the Tutorial: Send notifications to specific devices (Universal Windows Platform).

  2. 更新解决方案的 MainPage.xaml 文件,使之包括一个区域设置组合框:Update the solution's MainPage.xaml file to include a locale combobox:

    <Grid Margin="120, 58, 120, 80"  
            Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"  TextWrapping="Wrap" Text="Breaking News" FontSize="42" VerticalAlignment="Top"/>
        <ComboBox Name="Locale" HorizontalAlignment="Left" VerticalAlignment="Center" Width="200" Grid.Row="1" Grid.Column="0">
            <x:String>English</x:String>
            <x:String>French</x:String>
            <x:String>Mandarin</x:String>
        </ComboBox>
        <ToggleSwitch Header="World" Name="WorldToggle" Grid.Row="2" Grid.Column="0"/>
        <ToggleSwitch Header="Politics" Name="PoliticsToggle" Grid.Row="3" Grid.Column="0"/>
        <ToggleSwitch Header="Business" Name="BusinessToggle" Grid.Row="4" Grid.Column="0"/>
        <ToggleSwitch Header="Technology" Name="TechnologyToggle" Grid.Row="2" Grid.Column="1"/>
        <ToggleSwitch Header="Science" Name="ScienceToggle" Grid.Row="3" Grid.Column="1"/>
        <ToggleSwitch Header="Sports" Name="SportsToggle" Grid.Row="4" Grid.Column="1"/>
        <Button Content="Subscribe" HorizontalAlignment="Center" Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" Click="SubscribeButton_Click" />
    </Grid>
    
  3. Notifications 类中,向 StoreCategoriesAndSubscribeSubscribeToCategories 方法添加区域设置参数。In the Notifications class, add a locale parameter to the StoreCategoriesAndSubscribe and SubscribeToCategories methods.

    public async Task<Registration> StoreCategoriesAndSubscribe(string locale, IEnumerable<string> categories)
    {
        ApplicationData.Current.LocalSettings.Values["categories"] = string.Join(",", categories);
        ApplicationData.Current.LocalSettings.Values["locale"] = locale;
        return await SubscribeToCategories(categories);
    }
    
    public async Task<Registration> SubscribeToCategories(string locale, IEnumerable<string> categories = null)
    {
        var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
        if (categories == null)
        {
            categories = RetrieveCategories();
        }
    
        // Using a template registration. This makes supporting notifications across other platforms much easier.
        // Using the localized tags based on locale selected.
        string templateBodyWNS = String.Format("<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$(News_{0})</text></binding></visual></toast>", locale);
    
        return await hub.RegisterTemplateAsync(channel.Uri, templateBodyWNS, "localizedWNSTemplateExample", categories);
    }
    

    调用 RegisterTemplateAsync 而非 RegisterNativeAsync 方法。Instead of calling the RegisterNativeAsync method, call RegisterTemplateAsync. 请注册一个具体的通知格式,采用此通知格式的模板依赖于区域设置。You register a specific notification format in which the template depends on the locale. 另请提供模板名称(“localizedWNSTemplateExample”),因为可能需要注册多个模板(例如,一个模板用于 toast 通知,另一个模板用于磁贴)。You also provide a name for the template ("localizedWNSTemplateExample"), because you might want to register more than one template (for instance one for toast notifications and one for tiles). 另外,为了便于更新或删除,也需要为其命名。You also need to name them to update or delete them.

    如果一个设备使用同一标记注册多个模板,针对该标记的传入消息会导致多个通知发送到设备(一个通知对应一个模板)。If a device registers multiple templates with the same tag, an incoming message targeting that tag results in multiple notifications delivered to the device (one for each template). 当同一逻辑消息必须导致多个可视通知时,此行为很有用,例如在 Windows 应用商店应用程序显示徽章和 toast。This behavior is useful when the same logical message has to result in multiple visual notifications, for instance showing both a badge and a toast in a Windows Store application.

  4. 添加以下方法来检索存储的区域设置:Add the following method to retrieve the stored locale:

    public string RetrieveLocale()
    {
        var locale = (string) ApplicationData.Current.LocalSettings.Values["locale"];
        return locale != null ? locale : "English";
    }
    
  5. MainPage.xaml.cs 文件中更新按钮单击处理程序,以便检索“区域设置”组合框的当前值并将它提供给对 Notifications 类的调用:In the MainPage.xaml.cs file, update the button click handler to retrieve the current value of the Locale combo box and provide it to the call to the Notifications class:

    private async void SubscribeButton_Click(object sender, RoutedEventArgs e)
    {
        var locale = (string)Locale.SelectedItem;
    
        var categories = new HashSet<string>();
        if (WorldToggle.IsOn) categories.Add("World");
        if (PoliticsToggle.IsOn) categories.Add("Politics");
        if (BusinessToggle.IsOn) categories.Add("Business");
        if (TechnologyToggle.IsOn) categories.Add("Technology");
        if (ScienceToggle.IsOn) categories.Add("Science");
        if (SportsToggle.IsOn) categories.Add("Sports");
    
        var result = await ((App)Application.Current).notifications.StoreCategoriesAndSubscribe(locale,
                categories);
    
        var dialog = new MessageDialog("Locale: " + locale + " Subscribed to: " + 
            string.Join(",", categories) + " on registration Id: " + result.RegistrationId);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
    }
    
  6. 最后,在 App.xaml.cs 文件中更新 InitNotificationsAsync 方法以检索区域设置,并在订阅时使用该区域设置:Finally, in the App.xaml.cs file, update the InitNotificationsAsync method to retrieve the locale and use it when subscribing:

    private async void InitNotificationsAsync()
    {
        var result = await notifications.SubscribeToCategories(notifications.RetrieveLocale());
    
        // Displays the registration ID so you know it was successful
        if (result.RegistrationId != null)
        {
            var dialog = new MessageDialog("Registration successful: " + result.RegistrationId);
            dialog.Commands.Add(new UICommand("OK"));
            await dialog.ShowAsync();
        }
    }
    

运行 UWP 应用程序Run the UWP application

  1. 运行通用 Windows 平台应用程序。Run the Universal Windows Platform application. 等待“注册成功”消息出现。Wait until you see the Registration successful message.

    移动应用程序和注册

  2. 选择类别区域设置,然后单击“订阅”。Select the categories and locale, and click Subscribe. 应用程序将所选类别转换为标签并针对所选标签从通知中心请求注册新设备。The app converts the selected categories into tags and requests a new device registration for the selected tags from the notification hub.

    移动应用程序

  3. 此时会看到有关订阅确认消息。You see a confirmation message about the subscriptions.

    订阅消息

更新控制台应用,以便发送本地化通知Update console app to send localized notifications

发送模板通知时,只需提供一组属性。在本教程中,后端应用程序发送一组包含当前新闻的本地化版本的属性,例如:When you send template notifications you only need to provide a set of properties, in this tutorial, the backend application sends the set of properties containing the localized version of the current news, for instance:

{
    "News_English": "World News in English!",
    "News_French": "World News in French!",
    "News_Mandarin": "World News in Mandarin!"
}

在本部分,请在解决方案中更新控制台应用程序项目。In this section, you update the console application project in the solution. 使用以下代码修改前面创建的控制台应用中的 SendTemplateNotificationAsync 方法:Modify the SendTemplateNotificationAsync method in the console app you previously created with the following code:

Important

在代码中指定通知中心的名称和具有完全访问权限的连接字符串。Specify the name and connection string with full access for your notification hub in the code.

private static async void SendTemplateNotificationAsync()
{
    // Define the notification hub.
    NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(
        "<connection string with full access>", "<hub name>");

    // Sending the notification as a template notification. All template registrations that contain 
    // "messageParam" or "News_<local selected>" and the proper tags will receive the notifications. 
    // This includes APNS, WNS, and MPNS template registrations.
    Dictionary<string, string> templateParams = new Dictionary<string, string>();

    // Create an array of breaking news categories.
    var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"};
    var locales = new string[] { "English", "French", "Mandarin" };

    foreach (var category in categories)
    {
        templateParams["messageParam"] = "Breaking " + category + " News!";

        // Sending localized News for each tag too...
        foreach( var locale in locales)
        {
            string key = "News_" + locale;

            // Your real localized news content would go here.
            templateParams[key] = "Breaking " + category + " News in " + locale + "!";
        }

        await hub.SendTemplateNotificationAsync(templateParams, category);
    }
}

不管平台如何,此简单调用都会将本地化的新闻片段传送到所有设备,因为通知中心会生成正确的本机有效负载并将其传送到已订阅特定标记的所有设备。This simple call delivers the localized piece of news to all devices, irrespective of the platform, as your Notification Hub builds and delivers the correct native payload to all the devices subscribed to a specific tag.

运行控制台应用,以便发送本地化通知Run console app to send localized notification

运行控制台应用,以发送每个类别和每种支持语言的通知。Run the console app to send notifications for each category and in each supported language. 验证是否仅接收已订阅类别的通知,以及消息是否对应于所选区域设置。Verify that you only receive a notification for the categories you have subscribed to and the message is for the locale you selected.

![Notification messages](./media/notification-hubs-windows-store-dotnet-xplat-localized-wns-push-notification/notifications.png)

后续步骤Next steps

本教程介绍了如何向其标记与注册相关联的特定设备推送本地化通知。In this tutorial, you learned how to push localized notifications to specific devices that have tags associated with their registrations. 若要了解如何向可能会使用多个设备的特定用户推送通知,请转到以下教程:To learn how to push notifications to specific users who may be using more than one device, advance to the following tutorial: