Click here to Skip to main content
13,660,419 members
Click here to Skip to main content
Add your own
alternative version

Stats

78.6K views
3.5K downloads
88 bookmarked
Posted 21 Jan 2015
Licenced CPOL

Push Notification For Windows, iOS & Android - Quick, Easy and Flexible

, 22 Jan 2015
Rate this:
Please Sign up or sign in to vote.
FlexiPush (Push Notification) is a Quick, Easy and Flexible way to send a Push Notifications to the different platforms like Android, iOS and Windows instantly with your custom Payload as well

Introduction

FlexiPush is basically developed for Developer and Tester who will be developing and testing the apps with push notification features. The team (Developer and Tester) wanted to verify certain use cases which will depends on the server or push notification.

Why Push Notification is useful to us?

If something interesting or important happens and you wish to inform the user know about this, even though application is not running on the user’s device at that time Push Notification comes in picture. Let’s say, maybe the user received a new tweet when their favorite team won the match, or their ticket is booked, or someone sent you a message.

Luckily, Android, iOS and Windows provide solution to this. Instead of your app continuously checking these kind of stuff in background we can write a code on server to do the job instead of doing at client side.

What is Problem

Following are few examples where we can use FlexiPush:

  • If application is in background and notification comes?
  • Notification comes while traversing app by user, then how notification behaves?
  • User tap on notification then will it redirect to specific page or not?
  • Application will be able to get the required parameters on the respected page?

If you are not using FlexiPush then you will have to wait till notification comes from the server, and the waiting time may be in Minutes, Hours or a Days.

Solution for the Problem

FlexiPush is a Quick, Easy and Flexible way to send a Push Notifications to the different platforms like Android, iOS and Windows instantly with your custom Payload as well.

Technology Stack

  • ASP.Net MVC 4.0

ASP.NET is a development framework for building web pages and web sites with HTML, CSS, JavaScript and server scripting. ASP.NET supports three different development models:

  • Web Pages
  • MVC (Model View Controller)
  • Web Forms

Website: ASP.NET MVC 4

  • PushSharp

A server-side library for sending Push Notifications to iOS (iPhone/iPad APNS), Android (C2DM and GCM - Google Cloud Message), Windows Phone, Windows 8, Amazon, Blackberry, and (soon) FirefoxOS devices!

Website: Redth/PushSharp

  • SingnalR

ASP.NET SignalR is a new library for ASP.NET developers that makes developing real-time web functionality easy. SignalR allows bi-directional communication between server and client. Servers can now push content to connected clients instantly as it becomes available.

Website: Getting Started with SignalR 2

  • Bootstrap

Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.

Website: Bootstrap

Code Overview 

  • Model Class Diagram

  • Home Screen

On Home page, User will have option to choose Platform and Application Mode.

If Beginner mode is selected then user will be able to send only few parameters value to the notification center. This mode will be generally used by those users who does not know the custom JSON Paloyad and its type.

If Expert mode is selected then user will be able to send all possible JSON Payload. This feature will be generally used by those users who know each and every parameters of custom JSON Payload. Make sure at this point application will not responsible for verify each fields and attributes value or does not perform any validation. 

If user has entered invalid payload then they will not receive notification on the device because of improper payload.

  • Send Push Notification to Android Phone
    • Screen

    • Server Code in Controllers/NotificationController.cs
// POST: /Notification/SendToAndroid
        [HttpPost]
        public ActionResult SendToAndroid(AndroidPushNotificationModel model, string ClientID, string JSONPayload)
        {
            responseResult result = new responseResult();
            try
            {
                NotificationController.SocketClientID = ClientID;
                updateProcessStatusToClient(100, "Initializing", "Initializing GCM Push Channel Settings...");
                var push = new PushBroker();
//PushSharp Event Registration comes here….
                push.RegisterGcmService(new GcmPushChannelSettings(model.APIKey));
	
	//This will sending notification to android device based on Application mode selection.
                string JSONData = (isExpertMode()) ? JSONPayload : "{\"message\":\"" + model.NotificationText + "\",\"badge\":\"" + model.NotificationBadge + "\",\"sound\":\"" + model.SoundFile + "\"}";
                push.QueueNotification(new GcmNotification().ForDeviceRegistrationId(model.DeviceRegistrationID).WithJson(JSONData));
            }
            catch (Exception ex)
            {
                updateProcessStatusToClient(110, "Error in sending notification", ex.Message);
            }
            return Json(result, JsonRequestBehavior.AllowGet);
        }
  • Send Push Notification to iOS Phone
    • Screen

    • Server Code in Controllers/NotificationController.cs

First step is Uploading Certificate on server

[HttpPost]
        public void UploadFiles(string ClientID)
        {
            responseResult result = new responseResult();
            try
            {
                NotificationController.SocketClientID = ClientID;
                updateProcessStatusToClient(98, "Uploading Certificate...", "Uploading certificate on server");
                HttpPostedFileBase CertificateFile = null;
                foreach (string file in Request.Files)
                {
                    CertificateFile = Request.Files[file] as HttpPostedFileBase;
                    if (CertificateFile.ContentLength == 0) continue;
                    string uploadFileName = System.IO.Path.GetFileName(CertificateFile.FileName);
                    string uploadFilePathAndName = System.IO.Path.Combine(Server.MapPath(NotificationController.SaveCertificateFolder), uploadFileName);
                    if (System.IO.File.Exists(uploadFilePathAndName)) System.IO.File.Delete(uploadFilePathAndName);
                    CertificateFile.SaveAs(uploadFilePathAndName);
                }
                updateProcessStatusToClient(99, "Certificate Uploaded", "Certificate uploaded on server");
            }
            catch (Exception ex)
            {
                result.status = Status.Error;
                result.message = string.Format(RESULT_ERROR, ex.Message);
                updateProcessStatusToClient(104, "Notification Failed", ex.Message);
            }
        }

Second step is sending notification to the server

// POST: /Notification/SendToiOS
        [HttpPost]
        public ActionResult SendToiOS(iOSPushNotificationModel model, string ClientID, string JSONPayload)
        {
            model.isDisableCertificateCheck = false;
            responseResult result = new responseResult();
            try
            {
                NotificationController.SocketClientID = ClientID;
                updateProcessStatusToClient(100, "Initializing", "Initializing Push Channel Settings...");

                string uploadFileName = "";
                string certificateFile = "";
	//First check if default certificate is checked then notification will refer existing certificate used for sending notification to the server instead of uploading new certificate.
                if (model.UseDefaultCertificate == "0")
                {
                    certificateFile = System.IO.Path.Combine(Server.MapPath(NotificationController.DefaultCertificateFolder), DefaultCertificateFile);
                }
                else
                {
	    //This will upload new certificate on server
                    uploadFileName = System.IO.Path.GetFileName(model.CertificateFile);
                    certificateFile = System.IO.Path.Combine(Server.MapPath(NotificationController.SaveCertificateFolder), uploadFileName);
                }
                var push = new PushBroker();
//PushSharp Event Registration comes here….
                bool isProduction = (model.PublishType == PublishType.Development) ? false : true;
                var appleCert = System.IO.File.ReadAllBytes(certificateFile);
                int badge = (String.IsNullOrEmpty(model.NotificationBadge)) ? 0 : int.Parse(model.NotificationBadge);
                push.RegisterAppleService(new ApplePushChannelSettings(isProduction, appleCert, model.CertificatePassword, model.isDisableCertificateCheck));

                if (isExpertMode()) {
	     //This methos WithJSON was not available in PushSharp Library as of now, so I have made necessary changes to their existing library to fulfill the requirement.	
                    push.QueueNotification(new AppleNotification().ForDeviceToken(model.DeviceToken).WithJSON(JSONPayload));
}
                else
                    push.QueueNotification(new AppleNotification().ForDeviceToken(model.DeviceToken).WithAlert(model.NotificationText).WithBadge(badge));
            }
            catch (Exception ex)
            {
                result.status = Status.Error;
                result.message = string.Format(RESULT_ERROR, ex.Message);
                updateProcessStatusToClient(104, "Notification Failed", ex.Message);
            }
            return Json(result, JsonRequestBehavior.AllowGet);
        }

I have modified following files (PushSharp Library) to achieve the expert mode functionality.

  1. Added following method  in AppleFluentNotification.cs
    public static AppleNotification WithJSON(this AppleNotification n, string json)
            {
                if (n.Payload == null)
                    n.Payload = new AppleNotificationPayload();
                n.Payload.JSON = json;
                return n;
            }
  2. Added property in AppleNotificationAlert.cs
    public string JSON
            {
                get;
                set;
            }
  3. Added property in AppleNotificationPayload.cs
    public string JSON { get; set; }
    And updated method ToJson() with two lines of code.
    public string ToJson()
            {
    if (!string.IsNullOrEmpty(this.JSON))
                    return this.JSON;
            /*Rest of code will be untouched*/
    }
  • Send Push Notification to Windows Phone
    • Screen

    • Server Code in Controllers/NotificationController.cs

PushSharp library does not support to send custom Payload in XML format for windows platform when application mode is Expert, hence I have written code in pure .Net to send XML Payload to windows devices for Tile and Toast notifications.

Following is the method to send notification for windows platform.

// POST: /Notification/SendToWindows
 [HttpPost]
public ActionResult SendToWindows(WindowsPushNotificationModel model, string ClientID)
{
	//Following code will be used for Application mode is Expert
                    updateProcessStatusToClient(100, "Initializing", "Initializing Notification Request...");
                    string WindowsPhoneTarget = (model.NotificationType == Models.NotificationType.Toast) ? "toast" : "token";
                    string NotificationClass = (model.NotificationType == Models.NotificationType.Toast) ? "2" : "1";
                    string subscriptionUri = model.ChannelURI;
                    updateProcessStatusToClient(97, "Preparing Channel Headers", "Preparing headers for Windows phone channel");
                    HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
                    sendNotificationRequest.Method = "POST";
                    byte[] notificationMessage = Encoding.Default.GetBytes(model.JSONPayload);
                    sendNotificationRequest.ContentLength = notificationMessage.Length;
                    sendNotificationRequest.ContentType = "text/xml";
                    sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", WindowsPhoneTarget);
                    sendNotificationRequest.Headers.Add("X-NotificationClass", NotificationClass);
                    using (Stream requestStream = sendNotificationRequest.GetRequestStream())
                    {
                        requestStream.Write(notificationMessage, 0, notificationMessage.Length);
                    }
                    HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
                    string notificationStatus = response.Headers["X-NotificationStatus"];
                    string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
                    string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
                    switch (notificationStatus.ToUpper())
                    {
                        case "RECEIVED": //The push notification was received and dropped by the Push Notification Service
                        case "QUEUEFULL": //The server maintains a maximum of 30 notifications (regardless of type) for each URI. Once the limit of 30 is reached, all new messages sent to the server are discarded until the device reconnects and the queue can be flushed.
                        case "SUPPRESSED": //The push notification was received and dropped by the Push Notification Service. The Suppressed status can occur if the notification type was not enabled by calling BindToShellTile or BindToShellToast
                            updateProcessStatusToClient(101, "Notification Sent", string.Format("Notification Status:{0}, Channel Status:{1}, Device Connection Status:{2}", notificationStatus, notificationChannelStatus, deviceConnectionStatus));
                            break;
                        case "N/A":
                            updateProcessStatusToClient(104, "Notification Failed", "Coloud service sends a notification request with a bad XML document or malformed notification URI");
                            break;
                        default:
                            updateProcessStatusToClient(104, "Notification Failed", "The Push Notification Service is unable to process the request");
                            break;
                    }
//Following code will be used for Application mode is Beginner
                    updateProcessStatusToClient(100, "Initializing", "Initializing Push Channel Settings...");
                    int badge = (String.IsNullOrEmpty(model.NotificationBadge)) ? 0 : int.Parse(model.NotificationBadge);
                    var push = new PushBroker();
  
//PushSharp Event Registration comes here….
                    push.RegisterWindowsPhoneService();

                    if (model.NotificationType == Models.NotificationType.Tile)
                    {
                        push.QueueNotification(new WindowsPhoneTileNotification()
                            .ForEndpointUri(new Uri(model.ChannelURI))
                            .ForOSVersion(WindowsPhoneDeviceOSVersion.Eight)
                            .WithBatchingInterval(BatchingInterval.Immediate)
                            .WithTitle(model.NotificationText)
                            .WithCount(badge));
                    }
                    else if (model.NotificationType == Models.NotificationType.Toast)
                    {
                        push.QueueNotification(new WindowsPhoneToastNotification()
                           .ForEndpointUri(new Uri(model.ChannelURI))
                           .ForOSVersion(WindowsPhoneDeviceOSVersion.Eight)
                           .WithBatchingInterval(BatchingInterval.Immediate)
                           .WithNavigatePath(model.NavigatePath)
                           .WithText1(model.NotificationText)
                           .WithText2(model.NotificationText2));
                    }
}
  • SignalR Code Review
    • Installation
      1. Run the following command in the Package Manager Console

        PM> Install-Package Microsoft.AspNet.SignalR -Version 2.0.3

      2. Create Folder and File, then replace complete code from existing file.

        \Hubs\ProcessStatusNotifyHub.cs

      3. Include SignalR javascript files in file.

        <script src="~/Scripts/jquery.signalR-2.1.2.min.js">
        </script><script src="~/signalr/hubs"></script>

      4. Initialize SignalR.
        $(function () {
        var chat = $.connection.processStatusNotifyHub;
            	chat.client.notify = function (response) {
        }
            	$.connection.hub.start().done(function () {
               		$('#ClientID').val($.connection.hub.id);
               		 $('#' + platform + '-overlay').hide().find('div.log').removeClass('loading').addClass('log-' + platform);
            	});
        });
    • Notify Client for Process Status using Server Code

      Following method will be notifying client for every process step executed on server side, so user will get acknowledge from the server whether notification sent or not.

      static public void updateProcessStatusToClient(int status, string title, string message)
              {
                  if (prevStatus != status)
                  {
                      prevStatus = status;
                      string clientid = NotificationController.SocketClientID;
                      var hubContext = GlobalHost.ConnectionManager.GetHubContext<processstatusnotifyhub>();
                      SocketResponse response = new SocketResponse() { ClientID = clientid, Status = status, Title = title, Message = message, Time = DateTime.Now.ToString("hh:mm:ss tt") };
                      var json = new JavaScriptSerializer().Serialize(response);
                      hubContext.Clients.All.notify(json);
                  }
              }
      </processstatusnotifyhub>
    • Display Process Status using Client Code
      var res = JSON.parse(response);
              if (res.ClientID === $('#ClientID').val()) {
                  var push = $('#' + platform + '-notification');
                  //console.log('----' + res.Status + ':' + res.ClientID + ":" + res.Message + ":" + res.Time);
                  writeProcessLog(res.Time, res.Title);
                  switch (res.Status) {
                      case 100:
                          trackTimeout = window.setTimeout(function () {
                              writeProcessLog('', 'Request timeouts.
      Please verify you have entered the correct values. Please try again!');
                              $("div.close-log").show();
                          }, failureTimeout);
                          break;
                      case 101:
                          clearTimeout(trackTimeout);
                          window.setTimeout(function () {
                              $('#' + platform + '-overlay').hide();
                              if (push.css('display') == 'none') {
                                  $('#notificationText').text(notificationText);
                                  push.show().removeClass(NOTIFICATION_SHOW).addClass(NOTIFICATION_SHOW);
                              }
                          }, 1500);
                          break;
                      case 103:
                      case 104:
                      case 105:
                      case 106:
                      case 107:
                      case 108:
                      case 110:
                          clearTimeout(trackTimeout);
                          $("div.close-log").show();
                          break;
                  }
              }
    • JavaScript Code Snippet
      • Field Validation
        function checkValidation(fields) {
            var _cook = readCookie('ExpertMode');
            var _val = (_cook == null || _cook == "" || _cook == "false") ? false : true
            var fields, isValid = true;
            var msg = $('#NotificationText').val();
            switch (platform) {
                case 'android':
                    fields = [$('#APIKey'), $('#DeviceRegistrationID')];
                    if (_val) {
                        fields.push($('#JSONPayload'));
                        notificationText = notificationExpertText;
                    }
                    else {
                        fields.push($('#NotificationText'));
                        notificationText = msg;
                    }
                    break;
                case 'windows':
                    fields = [$('#NotificationType'), $('#ChannelURI')];
                    if (_val) {
                        fields.push($('#JSONPayload'));
                        notificationText = notificationExpertText;
                    }
                    else {
                        fields.push($('#NotificationText'));
                        notificationText = msg;
                    }
                    break;
                case 'ios':
                    fields = [$('#PublishType'), $('#DeviceToken'), $('#UseDefaultCertificate'), $('#CertificatePassword')];
                    if (_val) {
                        fields.push($('#JSONPayload'));
                        notificationText = notificationExpertText;
                    }
                    else {
                        fields.push($('#NotificationText'));
                        notificationText = msg;
                    }
                    break;
            }
            fields.forEach(function (field) {
                if (field.attr('id') == 'UseDefaultCertificate' && field.val() == "1" && $.trim($('#CertificateFile').val()) == "") {
                    $('#CertificateFile').addClass('required');
                    isValid = false;
                }
                else if (field.attr('id') == 'UseDefaultCertificate' && field.val() != "1") {
                    $('#CertificateFile').removeClass('required');
                }
        
                if ($.trim(field.val()) == "") {
                    field.addClass('required');
                    isValid = false;
                }
                else
                    field.removeClass('required');
            });
            return isValid;
        }
      • Upload Certificate File (for iOS only)
        var fd = new FormData();
                        fd.append("fileCertificate", $("#fileCertificate")[0].files[0]);
                        fd.append("ClientID", $("#ClientID").val());
                        $.ajax({
                            url: '/Notification/UploadFiles',
                            data: fd,
                            processData: false,
                            contentType: false,
                            type: 'POST',
                            success: function (data) {
                                submitFormData();
                            },
                            error: function (er) {
                                hideProcessLog('Error in Certificate Upload. Please try again!');
                            }
                        });
      • Submit Data to the Server
        function submitFormData() {
            var form = $('#formSend');
            var data = form.serialize();
            $.ajax({
                url: form.attr('action'),
                type: 'POST',
                data: data,
                dataType: 'json',
                success: function (result) {
                    if (result.status == 'Warning') {
                        hideProcessLog('Warning: ' + result.message);
                    }
                },
                error: function (er) {
                    hideProcessLog('Error: ' + er);
                }
            });
        }
      • Help and Notification Show/Hide Animation

        For showing animated help on the screen using below code:

        //For Notification
        $('#notificationText').text(notificationText);
        push.show().removeClass(NOTIFICATION_SHOW).addClass(NOTIFICATION_SHOW);
        //For Help
        $("span.help-field").on('click', function (e) {
                var index = Number($(this).data('index')) - 1;
                $('#' + platform + '-fieldhelp').html(help[index]).show().removeClass(HELP_SHOW).addClass(HELP_SHOW);
            });
        For hiding animated Help and Notification from the screen using below code:
        $('#android-notification, #android-fieldhelp, #windows-notification, #windows-fieldhelp, #ios-notification, #ios-fieldhelp').bind("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function () {
                var obj = $(this);
                var className = obj.attr('class');
               //For Notification
                if (className.indexOf('flipOutX') > -1) {
                    obj.removeClass(NOTIFICATION_HIDE).hide();
                }
               //For Help
                else if (className.indexOf('zoomOut') > -1) {
                    obj.removeClass(HELP_HIDE).hide();
                }
            });
  • Important Key Points

    • ​Android

    • iOS
      • Make sure you use the right Push certificate.
      • Apple allows you to generate one for connecting to Sandbox, and one for connecting to Production. You must use the right one, to match the provisioning profile you build your application with.For more details How to create APNS certificates.
    • Windows
      • Toast Notifications

        Toast Notifications are short text-based messages it consist of two strings of text, and appear at the top of the phone's display area

      • Tile Notifications

        Tile Notification can modify the appearance of app tiles that a phone user has pinned on their device. Tile notifications can specify a title, a count, and a background image that can be either a local or remote resource.

      • Raw Notifications

        Row Notification are similar to tile and toast notifications, except they do not have a particular display style or predefined payload format. The data contained in a raw notification is determined by the sender, and the app running on the phone must understand the content. Because the underlying operating system does not handle raw notifications, the app for which the notification is designed must be running in order to handle this type of notification. As of now this type of notification is not supported.

  • Important Fields Details

    • Android

      • API Key: The API KEY comes from your Google APIs Console App, under the API Access section, by choosing “Create new Server key...”.
      • Device Registration ID: Use your own Registration Id here that gets generated within your Android App itself.
    • iOS

      • Publish Type: If you are using a Development provisioning Profile, you must use the Sandbox push notification server. So you have to select Publish Type as “Development”.
        If you are using an AdHoc or AppStore provisioning profile, you must use the Production push notification server. So you have to select Publish Type as “Production”.
      • Device Token: The device token contains information that enables APNs (Apple Push Notification) to locate the device on which the client App is installed.
      • Select Certificate: This will provide an option to the user, for selecting existing Pre Defined certificate or upload new certificate.
      • New Certificate: To configure push notification for this iOS App ID, a Client SSL Certificate that allows your notification server to connect to the APN Service is required. Each iOS App ID requires its own Client SSL Certificate.
      • Certificate Password: SSL Certificate password for selected certificate file.
    • Windows
      • Notification Type: There are two types of alert will be supported
        Tile: Which are the Start screen tiles that represent and launch your app. 
        Toast: Which are app-specific pop-up notifications.
      • Channel URI: Use your own Endpoint Uri here that gets generated within your Windows Phone App itself.
      • Navigate Path: It will be redirecting to particular page when user tap on push notification. e.g. (/MainPage.xaml)
      • Notification Text2: A notification text2 is a short message, which will be displayed beside the title.
      • XML Payload: This will be visible only when Application Mode is set to Expert. Allow you to add custom data to the payload. Custom values must use the XML structured including <?xml version="1.0" encoding="utf-8"?>
    • Common
      • Notification Text: A notification text is a short message, which will be displayed at notification tray on which the client App is installed.
      • Notification Badge: The number to display as the badge of the app icon.
      • JSON Payload:  This will be visible only when Application Mode is set to Expert. Allow you to add custom data to the payload. Custom values must use the JSON structured and primitive types: dictionary (object), array, string, number, and Boolean.

Feedback

Please fill free to ask me if you would require any help for the same. Your valuable feedback, comment, suggestion and VOTE are highly appreciated.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sunasara Imdadhusen
Technical Lead Infostretch Ahmedabad-Gujarat
India India
Aspiring for a challenging carrier wherein I can learn, grow, expand and share my existing knowledge in meaningful and coherent way.

sunaSaRa Imdadhusen


AWARDS:

  1. 2nd Best Mobile Article of January 2015
  2. 3rd Best Web Dev Article of May 2014
  3. 2nd Best Asp.Net article of MAY 2011
  4. 1st Best Asp.Net article of SEP 2010


Read More Articles...

You may also be interested in...

Comments and Discussions

 
QuestionHi, I want to get push notification on windows desktop application? Is it possible? Pin
Member 948707126-Mar-18 8:08
memberMember 948707126-Mar-18 8:08 
QuestionHow to get device token IDs? Pin
Member 111376636-Jul-17 7:59
memberMember 111376636-Jul-17 7:59 
QuestionHow to get registeration id Pin
Member 1073043027-Oct-16 0:02
memberMember 1073043027-Oct-16 0:02 
QuestionHas Nuget Package Errors Pin
Member 1073043027-Oct-16 0:12
memberMember 1073043027-Oct-16 0:12 
AnswerRe: Full of Errors Pin
Member 1073043027-Oct-16 0:03
memberMember 1073043027-Oct-16 0:03 
GeneralRe: Full of Errors Pin
sonjasss24-Sep-17 22:01
membersonjasss24-Sep-17 22:01 
QuestionMultiple Device Pin
pdsweetpd22820-Oct-16 20:19
memberpdsweetpd22820-Oct-16 20:19 
Questionpush notification Pin
Member 1038646525-May-16 1:58
memberMember 1038646525-May-16 1:58 
QuestionPrevious notification gets vanished if I send a new notification to same device. What is solution of this issue Pin
Member 819648310-Apr-16 6:31
memberMember 819648310-Apr-16 6:31 
GeneralHello there are three missing files in the deploy pack Pin
Marco Castro22-Feb-16 3:39
memberMarco Castro22-Feb-16 3:39 
QuestionHow to get Windows phone Channel URI Pin
fidelis donald15-Mar-15 2:49
memberfidelis donald15-Mar-15 2:49 
AnswerRe: How to get Windows phone Channel URI Pin
Sunasara Imdadhusen15-Mar-15 19:10
professionalSunasara Imdadhusen15-Mar-15 19:10 
GeneralMy vote of 5 Pin
Renju Vinod15-Feb-15 17:20
professionalRenju Vinod15-Feb-15 17:20 
GeneralRe: My vote of 5 Pin
Sunasara Imdadhusen15-Feb-15 17:54
professionalSunasara Imdadhusen15-Feb-15 17:54 
GeneralGood Job my Vote of 5 Pin
Mubin M. Shaikh13-Feb-15 18:31
professionalMubin M. Shaikh13-Feb-15 18:31 
QuestionGreat Job. 5/5 Pin
Ali Danish Rizvi13-Feb-15 9:23
memberAli Danish Rizvi13-Feb-15 9:23 
GeneralRe: Great Job. 5/5 Pin
Sunasara Imdadhusen13-Feb-15 16:39
professionalSunasara Imdadhusen13-Feb-15 16:39 
GeneralMy vote of 5 Pin
Raul Iloc8-Feb-15 20:55
mvpRaul Iloc8-Feb-15 20:55 
GeneralRe: My vote of 5 Pin
Sunasara Imdadhusen8-Feb-15 21:19
professionalSunasara Imdadhusen8-Feb-15 21:19 
GeneralRe: My vote of 5 Pin
Sunasara Imdadhusen13-Feb-15 16:59
professionalSunasara Imdadhusen13-Feb-15 16:59 
AnswerRe: My vote of 5 Pin
Raul Iloc14-Feb-15 5:12
mvpRaul Iloc14-Feb-15 5:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01-2016 | 2.8.180810.1 | Last Updated 22 Jan 2015
Article Copyright 2015 by Sunasara Imdadhusen
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid