1

Background

Within my C# middle tier, I have a scheduled task that runs certain business logic every minute and then sends push notifications to iOS and Android devices accordingly. I use Urban Airship to facilitate the push notices which means that, in my code, I am just calling their API and then they handle the actual pushing to various devices. Here is what that code looks like:

public static void SendNotice(UaMessageModel messages)
{
    var audience = new NameValueCollection
        {
            {"alias", string.Join(", ", messages.UserIds)}
        };

    var notification = new NameValueCollection
        {
            {"alert", messages.Message}
        };

    var pushNotice = new NameValueCollection
        {
            {"audience", new JavaScriptSerializer().Serialize(audience)},
            {"notification", new JavaScriptSerializer().Serialize(notification)}
        };

    //ToDo: remove "validate" from URL when done testing.
    Utilities.PostWebRequest("https://go.urbanairship.com/api/push/validate/", "Basic XXXXXXXXX", pushNotice, "application/vnd.urbanairship+json; version=3;");
}


public class UaMessageModel
{
    public List<int> UserIds { get; set; }
    public string Message { get; set; }
}

Problem

When I put a break point at Utilities.PostWebRequest and hover over pushNotice, I only see the keys of the pushNotice NameValueCollection, but no values. Am I constructing this NameValueCollection incorrectly?

More Info

Whether pushNotice is constructed correctly or not, I still don't get any response from my WebClient post. This method works when I use just a simple, flat post object. Here is that code:

public static dynamic PostWebRequest(string url, string token, NameValueCollection obj, string accept)
{
    using (var wc = new WebClient())
    {
        wc.Headers.Add("Authorization", token);
        wc.Headers.Add("Accept", accept);
        return GetObjectFromJson(Encoding.UTF8.GetString(wc.UploadValues(url, "POST", obj)));
    }
}

Thanks in advance.

Matt Cashatt
  • 23,490
  • 28
  • 78
  • 111

1 Answers1

1

NameValueCollection is not a Dictionary. The JavascriptSerializer will not serialize it as you expect. To get your expected result you should convert the NameValueCollection to a Dictionary.

    NameValueCollection audience = new NameValueCollection();
    Data.Add("alias", "foobar");
    Data.Add("alias", "foobar2");

To output the values along with the keys you need to convert the NameValueCollection to a Dictionary like below:

    Dictionary<string, string> audienceDictionary = audience.AllKeys.ToDictionary(k => k, k => source[k]));

Our you can just use a Dictionary in your code instead of a NameValueCollection:

    Dictionary<string, string> audience = new Dictionary<string, string>();
    audience.Add("alias", string.Join(", ", messages.UserIds));

    Dictionary<string, string> notification = new Dictionary<string, string>();
    notification.Add("alert", messages.Message);

    Dictionary<string, string> pushNotice = new Dictionary<string, string>();
    pushNotice.Add("audience", new JavaScriptSerializer().Serialize(audience));
    pushNotice.Add("notification", new JavaScriptSerializer().Serialize(notification));

Edit:

Also take a look at this answer: https://stackoverflow.com/a/7003815/2488939

Community
  • 1
  • 1
The Mahahaj
  • 696
  • 6
  • 8
  • Thanks for your answer, but as far as I can tell, you must use a NameValueCollection when POSTing with `webclient`. – Matt Cashatt Apr 08 '14 at 14:35
  • @MatthewPatrickCashatt, You can serialize the dictionary using Newtonsoft's JsonConvert class or the built in JavascriptSerializer class and then convert the json string to bytes and post the data using webClient.UploadData like this MSDN example: http://msdn.microsoft.com/en-us/library/tdbbwh0a(v=vs.110).aspx, but I know this may not be an optimal solution for you. – The Mahahaj Apr 08 '14 at 14:54