0

I am in the process of changing one of our API calls

The current call is in the format

[url]/[user]/[itemid]

The new call is in the format:

[url]
{
 "user": ["user"],
 "category": ["category"],
 "itemIds": ["itemid1"], ["itemid2"]
}

In C# I currently build up the request as follows:

        string requestUrl = string.Format(_url, _userID, _itemID);

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
        string password = GetSignatureHash();

        request.Method = "GET";
        request.ContentType = "application/json";
        request.Accept = "application/json";
        request.Headers["Authorization"] = "Basic " + password;

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();

Please can someone advise me on how to populate the new HTTP Request with the detail given above?

Any assistance, advice or links would be greatly appreciated.

Richard Gale
  • 1,816
  • 5
  • 28
  • 45
  • Is the method for this API call changing from a GET to a POST? The first example looks like straightforward GET request, while the second looks like it contains a bit more information. – matt Nov 19 '13 at 16:20
  • Please include an example of [valid JSON](http://jsonlint.com/), or other usable description. – Tim S. Nov 19 '13 at 16:21
  • curl -H 'Accept: application/json' \ -u 123:XXXXXXXXXXXXXXXXXXXXXX \ https://url { "user": 1, "category": 1, "itemIds": ["012341234512340"], ["012341234512345"] } – Richard Gale Nov 19 '13 at 16:28

1 Answers1

1

You should use Json.NET as a serializer and write to the request stream. You should have a class that mirrors your data structure for your request. E.g.

public class MyRequest
{
    [JsonProperty("user")]
    public int User { get; set; }
    [JsonProperty("category")]
    public int Category { get; set; }
    [JsonProperty("itemIds")]
    public IList<string> ItemIds { get; set; }
}

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(_url);
string password = GetSignatureHash();

request.Method = "POST";
request.ContentType = "application/json";
request.Accept = "application/json";
request.Headers["Authorization"] = "Basic " + password;

using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
    var myRequest = new MyRequest { User = 1, Category = 1, 
                                    ItemIds = new[] { "1", "2" } };

    streamWriter.Write(JsonConvert.SerializeObject(myRequest));
    streamWriter.Flush();
}

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

The request sent will be like:

{
  "user": 1,
  "category": 1,
  "itemIds": [
    "1",
    "2"
  ]
}
Tim S.
  • 55,448
  • 7
  • 96
  • 122
  • Hi Thank you for your advise. I now get a response back. In order to Deserialize to a Business Object, do I need each property to carry: [JsonProperty(PropertyName = "category")]. And is deserialization best done using JsonConvert.DeserializeObject – Richard Gale Nov 20 '13 at 16:33
  • When deserializing in this scenario, you don't need to include the `JsonProperty` attributes, but it doesn't hurt to. I included them in my code so that it would serialize with that capitalization, while having properly (according to .Net convention) named properties. When deserializing, Json.NET is flexible enough to see that, e.g. `user` and `User` are really the same. And yes, `JsonConvert.DeserializeObject(myString)` should be best. – Tim S. Nov 20 '13 at 16:43
  • OK, well I am having issues Deserializing the following Json:
    `{"makes":[{"make":"APPLE","category":"1","serials":["0","D"],"models":[{"name":"IPHONE 4","colour":"WHITE","storage":"8GB"}]}]}`
    in that I just end up with an empty object every time.
    Do I need to handle the `"makes"` container in some way?
    – Richard Gale Nov 20 '13 at 17:00
  • @Richard yes, you need to handle the `makes` container, you should deserialize to a class with a property like `IList Makes`. You can see generated classes by pasting your JSON at http://json2csharp.com/ – Tim S. Nov 20 '13 at 17:02
  • Hi - Can your above Code be used but rather than using the Json.NET serializer, can I not use the pre-installed JavascriptSerializer? – Richard Gale Nov 21 '13 at 15:59
  • @Richard yes that should work, it'd just be different in how you serialize/deserialize and declare properties. I'd recommend Json.NET, but you should be able to get it working with that. – Tim S. Nov 21 '13 at 16:09
  • Im not sure if the issue is that without Json.Net, I cannot add [JsonProperty("user")] to my business object, as my request is now not being serialized correctly and I am getting a 401 error – Richard Gale Nov 21 '13 at 16:12
  • I'd recommend just changing the properties to match the JSON names: `public string user { get; set; }` and so on. [There is a way to do it](http://stackoverflow.com/a/2004216/781792) without changing that, but it's (IMO) a worse evil than using nonstandard property capitalization. – Tim S. Nov 21 '13 at 16:20
  • I have renamed the properties, but still no luck. – Richard Gale Nov 21 '13 at 16:21
  • If you can't figure it out from examples of JavascriptSerializer and trying to debug on your own, you should probably post a new question for that. – Tim S. Nov 21 '13 at 16:22