Udostępnij przez


Szybki przewodnik: powiadomienia push w Windows App SDK

W tym szybkim przewodniku utworzysz klasyczną aplikację na system Windows, która przy użyciu zestawu SDK aplikacji systemu Windowswysyła i odbiera powiadomienia wypychane.

Prerequisites

Przykładowa aplikacja

Ten przewodnik Szybki start przeprowadzi Cię przez proces dodawania obsługi powiadomień wypychanych do aplikacji w zestawie WINDOWS App SDK 1.7. Zobacz podobny kod do tego przewodnika Szybki start w przykładowych aplikacjach znajdujących się w usłudze GitHub. Upewnij się, że wyewidencjonuj gałąź z preferowaną wersją zestawu SDK aplikacji systemu Windows , aby zapoznać się z przykładami, które najlepiej pasują do projektu.

Przykłady dla każdej wersji zestawu SDK aplikacji systemu Windows można również znaleźć, wybierając gałąź wersji w repozytorium przykładów.

Odniesienie do API

Aby uzyskać dokumentację referencyjną interfejsu API dla powiadomień wypychanych, zobacz Microsoft.Windows.PushNotifications Namespace.

Konfigurowanie tożsamości aplikacji w usłudze Azure Active Directory (AAD)

Powiadomienia push w Windows App SDK używają tożsamości z Azure Active Directory (AAD). Poświadczenia Azure są wymagane podczas żądania URI kanału WNS oraz tokenów dostępu do wysyłania powiadomień push. Uwaga: nie obsługujemy przy użyciu powiadomień wypychanych zestawu SDK aplikacji systemu Windows w Centrum partnerskim firmy Microsoft.

Krok 1. Tworzenie rejestracji aplikacji usługi AAD

Zaloguj się do konta Azure i utwórz nowy zasób Rejestracja aplikacji AAD . Wybierz opcję Nowa rejestracja.

Krok 2: Podaj nazwę i wybierz opcję wielu dzierżawców.

  1. Podaj nazwę aplikacji.

  2. Powiadomienia push wymagają opcji multi-tenant, więc wybierz tę funkcję.

    1. Aby uzyskać więcej informacji na temat dzierżawców, zobacz Kto może zalogować się do aplikacji?.
  3. Wybierz pozycję Zarejestruj

  4. Zanotuj identyfikator aplikacji (klienta), ponieważ jest to identyfikator appid platformy Azure , którego będziesz używać podczas rejestracji aktywacji i żądania tokenu dostępu.

  5. Zanotuj identyfikator katalogu (dzierżawy), ponieważ jest to identyfikator dzierżawy platformy Azure, którego będziesz używać podczas żądania tokenu dostępu.

    Important

    rejestracja aplikacji AAD dzierżawcy Zanotuj swój identyfikator aplikacji (klienta) i identyfikator katalogu (dzierżawcy) .

  6. Zanotuj identyfikator obiektu , ponieważ jest to twoje Azure ObjectId, którego będziesz używać podczas wysyłania żądania kanału. Należy pamiętać, że nie jest to identyfikator obiektu wymieniony na stronie Podstawy . Zamiast tego, aby znaleźć prawidłowy identyfikator obiektu , kliknij nazwę aplikacji w aplikacji zarządzanej w katalogu lokalnym pole na stronie Essentials:

    Zrzut ekranu przedstawiający opcję Aplikacja zarządzana w katalogu lokalnym na stronie Podstawy

    Zrzut ekranu przedstawiający pole Identyfikator obiektu

    Note

    Aby uzyskać identyfikator obiektu, wymagana jest jednostka usługi . Jeśli nie jest ona skojarzona z aplikacją, wykonaj kroki opisane w jednym z następujących artykułów, aby utworzyć ją w portalu Azure lub przy użyciu wiersza polecenia:

    Użyj portalu, aby utworzyć aplikację i główną usługę Azure AD, która może uzyskiwać dostęp do zasobów

    tworzenie jednostki usługi przy użyciu programu Azure PowerShell z certyfikatem

Krok 3. Tworzenie wpisu tajnego na potrzeby rejestracji aplikacji

Klucz tajny będzie używany wraz z identyfikatorem aplikacji lub klienta platformy Azure, gdy będziesz żądać tokenu dostępu, aby wysyłać powiadomienia push.

Tajny klucz aplikacji AAD

Przejdź do pozycji Certyfikaty i wpisy tajne , a następnie wybierz pozycję Nowy klucz tajny klienta.

Important

Upewnij się, że klucz tajny został skopiowany po utworzeniu i przechowywany w bezpiecznej lokalizacji, na przykład w usłudze Azure Key Vault. Będzie ona widoczna tylko raz po utworzeniu.

Krok 4: Przypisz nazwę rodziny pakietów aplikacji do jej identyfikatora AppId platformy Azure

Jeśli aplikacja jest spakowana (w tym spakowana z lokalizacją zewnętrzną), możesz użyć tego przepływu do mapowania nazwy rodziny pakietów aplikacji (PFN) i jej identyfikatora AppId platformy Azure.

Jeśli twoja aplikacja jest spakowaną aplikacją Win32, utwórz żądanie mapowania nazwy rodziny pakietów (PFN), wysyłając wiadomość e-mail do Win_App_SDK_Push@microsoft.com z wierszem tematu "Żądanie mapowania powiadomień push zestawu SDK aplikacji Windows" i treścią "PFN: [twój PFN]", AppId: [twój APPId], Identyfikator obiektu: [twój ObjectId]. Żądania mapowania są wykonywane co tydzień. Po zakończeniu żądania mapowania otrzymasz powiadomienie.

Po utworzeniu identyfikatora AppId platformy Azure, identyfikatora ObjectId i wpisu tajnego możesz dodać te poświadczenia do przykładowego kodu poniżej.

Skonfiguruj swoją aplikację, aby odbierać powiadomienia push

Krok 1. Dodawanie zestawu SDK aplikacji systemu Windows i wymaganych pakietów NuGet

Następnie kliknij prawym przyciskiem myszy rozwiązanie w Eksploratorze rozwiązań i wybierz pozycję Zarządzaj pakietami NuGet.

W Menedżerze pakietów dodaj następujące pakiety:

  • Microsoft.WindowsAppSDK (minimalna wersja 1.1.0)
  • Microsoft.Windows.SDK.BuildTools (minimalna wersja 10.0.22000.194)
  • Microsoft.Windows.CppWinRT, (minimalna wersja 2.0.210930.14)
  • Microsoft.Windows.ImplementationLibrary, (minimalna wersja 1.0.210930.1)

Jeśli po raz pierwszy używasz zestawu SDK aplikacji systemu Windows w projekcie i jest on spakowany z lokalizacją zewnętrzną lub rozpakowany, zainicjuj zestaw SDK aplikacji systemu Windows, dodając następującą właściwość do pliku projektu:

<!-- your .vcxproj or .proj file -->
<PropertyGroup Label="Globals">
    <!-- Other properties -->
    <WindowsPackageType>None</WindowsPackageType>
</PropertyGroup>

lub użyj interfejsu API programu inicjjącego. Aby uzyskać więcej informacji, zobacz Use the Windows App SDK runtime for apps packaged with external location or unpackaged (Używanie środowiska uruchomieniowego zestawu SDK aplikacji systemu Windows dla aplikacji spakowanych z lokalizacją zewnętrzną lub rozpakowywaniem ).

Note

Jeśli zestaw SDK nie zostanie zainicjowany, aplikacja zostanie wyrzucona System.Runtime.InteropServices.COMException (0x80040154): Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)) i nie zostanie uruchomiona.

Krok 2. Dodawanie przestrzeni nazw

Następnie dodaj przestrzeń nazw dla powiadomień wypychanych Microsoft.Windows.PushNotificationszestawu SDK aplikacji systemu Windows.

#include <winrt/Microsoft.Windows.PushNotifications.h>

using namespace winrt::Microsoft::Windows::PushNotifications;

Jeśli wystąpi błąd "Nie można odnaleźć pliku Microsoft.Windows.PushNotifications", prawdopodobnie oznacza to, że pliki nagłówkowe nie zostały wygenerowane. Aby rozwiązać ten problem, upewnij się, że masz zainstalowane powyżej pakiety, oznacz jako komentarz instrukcje include i using powodujące błąd, a następnie ponownie skompiluj aplikację, aby wygenerować pliki nagłówka. Po pomyślnym zakończeniu kompilacji usuń komentarz z instrukcji include i using i skompiluj projekt. Powinno to usunąć błąd.

Krok 3. Dodawanie aktywatora COM do manifestu aplikacji

Important

Jeśli aplikacja jest rozpakowana (oznacza to, że nie ma tożsamości pakietu w czasie wykonywania), przejdź do kroku 4: Rejestrowanie i reagowanie na powiadomienia wypychane podczas uruchamiania aplikacji.

Jeśli aplikacja jest spakowana (w tym spakowana z lokalizacją zewnętrzną): otwórz Package.appxmanifest. Dodaj następujący element w elemecie <Application> . Zastąp Idwartości , Executablei DisplayName tymi specyficznymi dla aplikacji.

<!--Packaged apps only-->
<!--package.appxmanifest-->

<Package
  ...
  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
  ...
  <Applications>
    <Application>
      ...
      <Extensions>

        <!--Register COM activator-->    
        <com:Extension Category="windows.comServer">
          <com:ComServer>
              <com:ExeServer Executable="SampleApp\SampleApp.exe" DisplayName="SampleApp" Arguments="----WindowsAppRuntimePushServer:">
                <com:Class Id="[Your app's Azure AppId]" DisplayName="Windows App SDK Push" />
            </com:ExeServer>
          </com:ComServer>
        </com:Extension>
    
      </Extensions>
    </Application>
  </Applications>
 </Package>    

Note

Przykład ukończonej klasy języka C++ można znaleźć po kroku 5. Kroki 4 i 5 zawierają wskazówki krok po kroku, aby dodać każdy element w ostatnim przykładzie.

Krok 4. Rejestrowanie i odpowiadanie na powiadomienia wypychane podczas uruchamiania aplikacji

Zaktualizuj metodę aplikacji main() , aby dodać następujące elementy:

  1. Zarejestruj aplikację, aby otrzymywać powiadomienia push, wywołując PushNotificationManager::Default().Register().
  2. Sprawdź źródło żądania aktywacji, wywołując metodę AppInstance::GetCurrent(). GetActivatedEventArgs(). Jeśli aktywacja została wyzwolona z powiadomienia push, odpowiedz biorąc pod uwagę ładunek powiadomienia.

Important

Należy wywołać funkcję PushNotificationManager::Default().Zarejestrować przed wywołaniem AppInstance.GetCurrent.GetActivatedEventArgs.

Dodawanie procedur obsługi zdarzeń pierwszego planu

Aby obsłużyć zdarzenie na pierwszym planie, zarejestruj procedurę obsługi elementu PushNotificationManager.PushReceived.

Important

Należy również zarejestrować wszystkie programy obsługi zdarzeń PushNotificationManager.PushReceived przed wywołaniem metody PushNotificationManager.Register(). W przeciwnym razie zostanie zgłoszony następujący wyjątek środowiska uruchomieniowego:

System.Runtime.InteropServices.COMException: Element not found. Must register event handlers before calling Register().

Dodaj sprawdzanie PushNotificationManager::IsSupported()

Następnie dodaj sprawdzenie, czy interfejsy API pushNotification są obsługiwane za pomocą elementu PushNotificationManager.IsSupported(). Jeśli nie, zalecamy użycie sondowania lub własnej implementacji gniazd niestandardowych.

Po potwierdzeniu obsługi powiadomień wypychanych dodaj zachowanie na podstawie elementu PushNotificationReceivedEventArgs.

Krok 5. Żądanie identyfikatora URI kanału usługi WNS i zarejestrowanie go na serwerze WNS

Identyfikatory URI kanału WNS to punkty końcowe HTTP do wysyłania powiadomień push. Każdy użytkownik musi zażądać identyfikatora URI kanału i zarejestrować go na serwerze WNS, aby otrzymywać powiadomienia push.

Note

Identyfikatory URI kanału WNS wygasają po upływie 30 dni.

auto channelOperation{ PushNotificationManager::Default().CreateChannelAsync(winrt::guid("[Your app's Azure ObjectID]")) };

Jeśli obserwujesz kod samouczka, dodaj identyfikator obiektu platformy Azure tutaj:

// To obtain an AAD RemoteIdentifier for your app,
// follow the instructions on https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app
winrt::guid remoteId{ "00000000-0000-0000-0000-000000000000" }; // Replace this with your own Azure ObjectId

PushNotificationManager podejmie próbę utworzenia URI kanału, automatycznie ponawiając próbę przez nie więcej niż 15 minut. Utwórz procedurę obsługi zdarzeń, aby poczekać na zakończenie wywołania. Po zakończeniu wywołania, jeśli przebiegło pomyślnie, zarejestruj identyfikator URI na serwerze WNS.

Przykładowy kod

#include <iostream>
#include <winrt/Microsoft.Windows.PushNotifications.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Microsoft.Windows.AppLifecycle.h>
#include <winrt/Windows.ApplicationModel.Background.h>
#include <wil/cppwinrt.h>
#include <wil/result.h>

using namespace winrt::Microsoft::Windows::PushNotifications;
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Windows::AppLifecycle;

// To obtain an AAD RemoteIdentifier for your app,
// follow the instructions on https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app
winrt::guid remoteId{ "00000000-0000-0000-0000-000000000000" }; // Replace this with your own Azure ObjectId

winrt::Windows::Foundation::IAsyncOperation<PushNotificationChannel> RequestChannelAsync()
{
    auto channelOperation = PushNotificationManager::Default().CreateChannelAsync(remoteId);

    // Set up the in-progress event handler
    channelOperation.Progress(
        [](auto&& sender, auto&& args)
        {
            if (args.status == PushNotificationChannelStatus::InProgress)
            {
                // This is basically a noop since it isn't really an error state
                std::cout << "Channel request is in progress." << std::endl << std::endl;
            }
            else if (args.status == PushNotificationChannelStatus::InProgressRetry)
            {
                LOG_HR_MSG(
                    args.extendedError,
                    "The channel request is in back-off retry mode because of a retryable error! Expect delays in acquiring it. RetryCount = %d",
                    args.retryCount);
            }
        });

    auto result = co_await channelOperation;

    if (result.Status() == PushNotificationChannelStatus::CompletedSuccess)
    {
        auto channelUri = result.Channel().Uri();

        std::cout << "channelUri: " << winrt::to_string(channelUri.ToString()) << std::endl << std::endl;

        auto channelExpiry = result.Channel().ExpirationTime();

        // Caller's responsibility to keep the channel alive
        co_return result.Channel();
    }
    else if (result.Status() == PushNotificationChannelStatus::CompletedFailure)
    {
        LOG_HR_MSG(result.ExtendedError(), "We hit a critical non-retryable error with channel request!");
        co_return nullptr;
    }
    else
    {
        LOG_HR_MSG(result.ExtendedError(), "Some other failure occurred.");
        co_return nullptr;
    }

};

PushNotificationChannel RequestChannel()
{
    auto task = RequestChannelAsync();
    if (task.wait_for(std::chrono::seconds(300)) != AsyncStatus::Completed)
    {
        task.Cancel();
        return nullptr;
    }

    auto result = task.GetResults();
    return result;
}

void SubscribeForegroundEventHandler()
{
    winrt::event_token token{ PushNotificationManager::Default().PushReceived([](auto const&, PushNotificationReceivedEventArgs const& args)
    {
        auto payload{ args.Payload() };

        std::string payloadString(payload.begin(), payload.end());
        std::cout << "\nPush notification content received in the FOREGROUND: " << payloadString << std::endl;
    }) };

    std::cout << "Push notification foreground event handler registered." << std::endl;
}

int main()
{
    // Set up an event handler, so we can receive notifications in the foreground while the app is running.
    // You must register notification event handlers before calling Register(). Otherwise, the following runtime
    // exception will be thrown: System.Runtime.InteropServices.COMException: 'Element not found. Must register
    // event handlers before calling Register().'
    SubscribeForegroundEventHandler();

    // Register the app for push notifications.
    PushNotificationManager::Default().Register();

    auto args{ AppInstance::GetCurrent().GetActivatedEventArgs() };
    switch (args.Kind())
    {
        case ExtendedActivationKind::Launch:
        {
            std::cout << "App launched by user or from the debugger." << std::endl;
            if (PushNotificationManager::IsSupported())
            {
                std::cout << "Push notifications are supported on this device." << std::endl;

                // Request a WNS Channel URI which can be passed off to an external app to send notifications to.
                // The WNS Channel URI uniquely identifies this app for this user and device.
                PushNotificationChannel channel{ RequestChannel() };
                if (!channel)
                {
                    std::cout << "\nThere was an error obtaining the WNS Channel URI" << std::endl;

                    if (remoteId == winrt::guid{ "00000000-0000-0000-0000-000000000000" })
                    {
                        std::cout << "\nThe ObjectID has not been set. Refer to the readme file accompanying this sample\nfor the instructions on how to obtain and setup an ObjectID" << std::endl;
                    }
                }

                std::cout << "\nPress 'Enter' at any time to exit App." << std::endl;
                std::cin.ignore();
            }
            else
            {
                std::cout << "Push notifications are NOT supported on this device." << std::endl;
                std::cout << "App implements its own custom socket here to receive messages from the cloud since Push APIs are unsupported." << std::endl;
                std::cin.ignore();
            }
        }
        break;

        case ExtendedActivationKind::Push:
        {
            std::cout << "App activated via push notification." << std::endl;
            PushNotificationReceivedEventArgs pushArgs{ args.Data().as<PushNotificationReceivedEventArgs>() };

            // Call GetDeferral to ensure that code runs in low power
            auto deferral{ pushArgs.GetDeferral() };

            auto payload{ pushArgs.Payload() };

            // Do stuff to process the raw notification payload
            std::string payloadString(payload.begin(), payload.end());
            std::cout << "\nPush notification content received in the BACKGROUND: " << payloadString.c_str() << std::endl;
            std::cout << "\nPress 'Enter' to exit the App." << std::endl;

            // Call Complete on the deferral when finished processing the payload.
            // This removes the override that kept the app running even when the system was in a low power mode.

            deferral.Complete();
            std::cin.ignore();
        }
        break;

        default:
            std::cout << "\nUnexpected activation type" << std::endl;
            std::cout << "\nPress 'Enter' to exit the App." << std::endl;
            std::cin.ignore();
            break;
    }
}

Krok 6. Kompilowanie i instalowanie aplikacji

Użyj programu Visual Studio, aby skompilować i zainstalować aplikację. Kliknij prawym przyciskiem myszy plik rozwiązania w Eksploratorze rozwiązań i wybierz polecenie Wdróż. Program Visual Studio skompiluje aplikację i zainstaluje ją na maszynie. Aplikację można uruchomić, uruchamiając ją za pomocą menu Start lub debugera programu Visual Studio.

Konsola kodu samouczka będzie wyglądać następująco:

działająca konsola przykładowa

Token będzie potrzebny do wysłania powiadomienia wypychanego do aplikacji.

Wyślij powiadomienie push do swojej aplikacji

Na tym etapie cała konfiguracja jest ukończona, a serwer WNS może wysyłać powiadomienia push do aplikacji klienckich. W poniższych krokach zapoznaj się z nagłówkami Żądania i odpowiedzi serwera powiadomień wypychanych, aby uzyskać więcej szczegółów.

Krok 1. Żądanie tokenu dostępu

Aby wysłać powiadomienie push, serwer WNS musi najpierw zażądać tokenu dostępu. Wyślij żądanie HTTP POST wraz z Twoim identyfikatorem dzierżawy Azure, identyfikatorem aplikacji Azure i tajnym kluczem. Aby uzyskać informacje na temat pobierania identyfikatora dzierżawy platformy Azure i identyfikatora aplikacji platformy Azure, zobacz Pobierz identyfikatory dzierżawy i aplikacji do logowania.

Przykładowe żądanie HTTP:

POST /{tenantID}/oauth2/v2.0/token Http/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 160

grant_type=client_credentials&client_id=<Azure_App_Registration_AppId_Here>&client_secret=<Azure_App_Registration_Secret_Here>&scope=https://wns.windows.com/.default/

Przykładowe żądanie języka C#:

//Sample C# Access token request
var client = new RestClient("https://login.microsoftonline.com/{tenantID}/oauth2/v2.0");
var request = new RestRequest("/token", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "client_credentials");
request.AddParameter("client_id", "[Your app's Azure AppId]");
request.AddParameter("client_secret", "[Your app's secret]");
request.AddParameter("scope", "https://wns.windows.com/.default");
RestResponse response = await client.ExecutePostAsync(request);
Console.WriteLine(response.Content);

Jeśli żądanie zakończy się pomyślnie, otrzymasz odpowiedź zawierającą token w polu access_token .

{
    "token_type":"Bearer",
    "expires_in":"86399",
    "ext_expires_in":"86399",
    "expires_on":"1653771789",
    "not_before":"1653685089",
    "access_token":"[your access token]"
}

Krok 2. Wysyłanie nieprzetworzonego powiadomienia

Utwórz żądanie HTTP POST zawierające token dostępu uzyskany w poprzednim kroku oraz zawartość powiadomienia wypychanego, które chcesz wysłać. Zawartość powiadomienia push zostanie dostarczona do aplikacji.

POST /?token=[The token query string parameter from your channel URL. E.g. AwYAAABa5cJ3...] HTTP/1.1
Host: dm3p.notify.windows.com
Content-Type: application/octet-stream
X-WNS-Type: wns/raw
Authorization: Bearer [your access token]
Content-Length: 46

{ Sync: "Hello from the Contoso App Service" }
var client = new RestClient("[Your channel URL. E.g. https://wns2-by3p.notify.windows.com/?token=AwYAAABa5cJ3...]");
var request = new RestRequest();
request.Method = Method.Post; 
request.AddHeader("Content-Type", "application/octet-stream");
request.AddHeader("X-WNS-Type", "wns/raw");
request.AddHeader("Authorization", "Bearer [your access token]");
request.AddBody("Notification body");
RestResponse response = await client.ExecutePostAsync(request);");

Krok 3. Wysyłanie powiadomienia aplikacji opartej na chmurze

Jeśli interesuje Cię tylko wysyłanie nieprzetworzonych powiadomień, zignoruj ten krok. Aby wysłać powiadomienie aplikacji opartej na chmurze, znane również jako powiadomienie push, najpierw postępuj zgodnie z instrukcjami w Szybki start: powiadomienia aplikacji w Windows App SDK. Powiadomienia aplikacji mogą być powiadomieniami push (wysyłane z chmury) lub wysyłane lokalnie. Wysyłanie powiadomienia aplikacji opartej na chmurze jest podobne do wysyłania nieprzetworzonego powiadomienia w kroku 2, z wyjątkiem sytuacji, gdy nagłówek X-WNS-Type jest toast, typ zawartości Content-Type jest text/xml, a zawartość zawiera ładunek XML powiadomienia aplikacji. Aby uzyskać więcej informacji na temat konstruowania ładunku XML, zobacz Schemat XML powiadomień .

Utwórz żądanie HTTP POST zawierające token dostępu i zawartość powiadomienia aplikacji źródłowej w chmurze, które chcesz wysłać. Zawartość powiadomienia push zostanie dostarczona do aplikacji.

POST /?token=AwYAAAB%2fQAhYEiAESPobjHzQcwGCTjHu%2f%2fP3CCNDcyfyvgbK5xD3kztniW%2bjba1b3aSSun58SA326GMxuzZooJYwtpgzL9AusPDES2alyQ8CHvW94cO5VuxxLDVzrSzdO1ZVgm%2bNSB9BAzOASvHqkMHQhsDy HTTP/1.1
Host: dm3p.notify.windows.com
Content-Type: text/xml
X-WNS-Type: wns/toast
Authorization: Bearer [your access token]
Content-Length: 180

<toast><visual><binding template="ToastGeneric"><text>Example cloud toast notification</text><text>This is an example cloud notification using XML</text></binding></visual></toast>
var client = new RestClient("https://dm3p.notify.windows.com/?token=AwYAAAB%2fQAhYEiAESPobjHzQcwGCTjHu%2f%2fP3CCNDcyfyvgbK5xD3kztniW%2bjba1b3aSSun58SA326GMxuzZooJYwtpgzL9AusPDES2alyQ8CHvW94cO5VuxxLDVzrSzdO1ZVgm%2bNSB9BAzOASvHqkMHQhsDy");
client.Timeout = -1;

var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "text/xml");
request.AddHeader("X-WNS-Type", "wns/toast");
request.AddHeader("Authorization", "Bearer <AccessToken>");
request.AddParameter("text/xml", "<toast><visual><binding template=\"ToastGeneric\"><text>Example cloud toast notification</text><text>This is an example cloud notification using XML</text></binding></visual></toast>",  ParameterType.RequestBody);
Console.WriteLine(response.Content);

Resources