Envíe una notificación de inserción desde un dispositivo Windows Phone al servicio web

I have a question about the push notification service of the Windows Phone 7 device: I can now send a push notification, using a web application to a phone, changing the data of the tile. But the problem is: when I start the app, I need to display the URI in the debugger output, and then copy-paste it inside the web application, which in turn will contact the MPNS, which is fine for an update, once to a single phone. But I want to create a webservice that can make multiple calls automatically, retrieve the URI of the application ( which changes after closing-and-opening the app, I think ) and send a push notification to it. But I haven't found an MSDN - topic that deals with this. They just use commends, saying : "to be replaced later with the URI needed." So my question is: how do I use the phone to send such a message to the webservice, respond to it, and connect to the phone again, handling such request? and also: do I need an authenticated webservice, or is there a debug version?

This is what I have thus far :

  /// <summary>
    /// Setup a connection with a webservice, in order to update a shell, either a toast- or a tile shell.
    /// </summary>
    /// <param name="shellType">The type of shell you wish to update</param>
    public void SetupShellChannel ( ShellBindType shellType )
        //holds the push notification that is created. Since we can only have one notification channel open at any one time, 
        //we will need to check for existance. That is why, the channelName shouldn't be changed
        HttpNotificationChannel _httpChannel = HttpNotificationChannel.Find( _channelName );

        //if the _httpChannel was not found ( read: does not exist )
        if ( _httpChannel == null )
            _httpChannel = new HttpNotificationChannel( _channelName  );
            _httpChannel.Open( );

            //because there is more than one shelltype we can open, we will use a switch to call the method we seek
            BindToShell( _httpChannel, shellType );
            //Only one push notification service is allowed per application, so we cannot send a tile notification, as well as 
            //a toast message notification. When we attempt this, we get a InvalidOperationException
            //in this case, the _httpChannel did already exist, but the problem is, we cannot just add the eventHandlers, 
            //because there is the danger that it didn't exist, and we would get a null pointer exception.
            //_httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>( httpChannel_ChannelUriUpdated );
            //_httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>( httpChannel_ErrorOccurred );

            //For testing purposes, we now display the URI to the user, and as output. Normally, we would pass this URI back to the webserver
            System.Diagnostics.Debug.WriteLine( _httpChannel.ChannelUri.ToString( ) );

        //if ( _httpChannel.ChannelUri )

        //When the URI is updated, we want this to be sent to the server as well, so we know that the adress has changed, 
        //and don't just send data somewhere into the void. Also, when encountering an error, we want to show the user when 
        //an error has occured.
        _httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>( HttpChannel_ChannelUriUpdated );
        _httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>( HttpChannel_ErrorOccurred );

    //here, also we would return the URI to the server, but for debugging purposes, we display them to the user.
    void HttpChannel_ChannelUriUpdated( object sender, NotificationChannelUriEventArgs e )
        Deployment.Current.Dispatcher.BeginInvoke( ( ) => 
            System.Diagnostics.Debug.WriteLine( e.ChannelUri.ToString( ) );
            MessageBox.Show( String.Format( "the URI is {0}", e.ChannelUri.ToString( ) ) );
        } );

    private void BindToShell( HttpNotificationChannel channel, ShellBindType shellType )
        switch ( shellType )
            case ShellBindType.BindToShellTile:
                channel.BindToShellTile( );
            case ShellBindType.BindToShellToast:
                channel.BindToShellToast( );

    void HttpChannel_ErrorOccurred( object sender, NotificationChannelErrorEventArgs e )
        //getting an error would be caugth here, and then displayed to the user.
        Deployment.Current.Dispatcher.BeginInvoke( ( ) =>
                MessageBox.Show( String.Format( "A push notification {0} error occured. {1}{(2)}{3}", 
                    e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData ) );
            } );

preguntado el 31 de enero de 12 a las 16:01

Can you explain the first part of qn - how do I use the phone to send such a message to the webservice, respond to it, and connect to the phone again, handling such request. -

2 Respuestas

Ok I understand your question. What I have done is once I get teh URI from MPNS, I call a web method on a service with this as a parameter - Subscribe(int subscriberId, Uri channelUri);

So you need to make sure you generate a subscriberId in your app to identify a user and store it in Isolated Storage. This can be a GUID.

The onus is now upon hte server to save the Subscriber to Uri mapping in persistant storage.

Also you need to provide UnSubscribe method for user to opt out of the push notification. This is one of the certification requirement for Push notifications.

Now about your second question - Yes, you would need to secure your services - you dont want to be handling with unknown requests.

What i do personally, divide it into 2 services - Publishing service and subscription service. The Publishing service will send out hte notifications while subscription will have the subscribe/unsubscribe methods.

Respondido 08 Feb 12, 10:02

Thank you for yout answer =D I had already found the answer though, and did something similar idd. I did not yet implement the two seperate webservices, which seems like a very plausable thing to do, since I can than manage the devices receiving the notification. - GeekPeek

I guess you are trying to ask that you can send push notification from Windows Phone itself or not instead using any other server side ASP/PHP like explained in Sample Applications in MSDN. Yes. You can send notifications from phone/device itself. You have to just change Send function of Sample app as given in MSDN. Reply if you have any queries.

static async Task<string> SendPushNotification(string textToSend)
    //You can maintain a DB to query different channel URIs of devices
    string subscriptionUri = "<Uri To Which You Want Send Notification>";
    HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
    sendNotificationRequest.Method = "POST";

    string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
        "<wp:Notification xmlns:wp=\"WPNotification\">" +
           "<wp:Toast>" +
                "<wp:Text1>" + textToSend + "</wp:Text1>" +
                "<wp:Param>/NotificationDetails.xaml?Message=" + textToSend + "</wp:Param>" +
           "</wp:Toast> " +
    byte[] notificationMessage = Encoding.UTF8.GetBytes(toastMessage);

    sendNotificationRequest.ContentLength = notificationMessage.Length;
    sendNotificationRequest.ContentType = "text/xml";
    sendNotificationRequest.Headers["X-WindowsPhone-Target"] = "toast";
    sendNotificationRequest.Headers["X-NotificationClass"] = "2";

    using (var requestStream = await Task.Factory.FromAsync<Stream>(sendNotificationRequest.BeginGetRequestStream, sendNotificationRequest.EndGetRequestStream, null))
        requestStream.Write(notificationMessage, 0, notificationMessage.Length);

    string notificationStatus;
    using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(sendNotificationRequest.BeginGetResponse, sendNotificationRequest.EndGetResponse, null)))
        //StreamReader reader = new StreamReader(response.GetResponseStream());
        //result = reader.ReadToEnd();
        notificationStatus = response.Headers["X-NotificationStatus"];
    return notificationStatus;

Respondido 18 ago 14, 16:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.