There’s a lot we can learn from Microsoft, some of it from well designed software and most some of it from poorly designed software. This particular post is about the latter.

I was working in .NET today (yes, it was a sad day) and I needed to do the following:

  • Serialize an object to valid JSON
  • Send that JSON to a HTTP service via an HTTP POST
  • Verify the response (200 status code)

Sounds fairly simple. In Ruby, it looks something like this:

1 uri = URI.parse('http://localhost:4567')
2 Net::HTTP.start(uri.host, uri.port) do |http|
3   headers = {'Content-Type': 'application/json'}
4   http.post2('/service_path', data.to_json, headers) do |resp|
5     return resp.code == '200'
6   end
7 end

I would expect the .NET version to be fairly similar (but longer of course). However, I was a little off in my assumptions. Let me walk you through the steps I took just to get the same functionality in the Ruby code above. As we go along, I’ll point out the anti-patterns found in the .NET standard lib.

Step 1 - Defining a Data Contract

 1 [DataContract]
 2 public class MyObjectDataContract
 3 {
 4     [DataMember(Name = "user_id")]
 5     public int? UserId { get; set; }
 6  
 7     [DataMember(Name = "car_id")]
 8     public int? CarId { get; set; }
 9  
10     [DataMember(Name = "template_data")]
11     public Dictionary<String, object> TemplateData { get; set; }
12  
13     [DataMember(Name = "key")]
14     public Dictionary<String, object> Key { get; set; }
15 }

Nothing out of the ordinary here. Everything seems to be going well so far. I’ve defined my basic object that I would like to serialize to JSON and life is peachy.

Step 2 - Serialize the JSON

Based on what I found on the internet, this should suffice:

1 // assume myObjectDataContract is already set and defined
2  
3 MemoryStream jsonStream = new MemoryStream();
4 DataContractJsonSerializer ser = new DataContractJsonSerializer(
5     typeof(MyObjectDataContract));
6 ser.WriteObject(jsonStream, myObjectDataContract);


Anit-Pattern #1 - Organize your standard library in a way that makes no logical sense

I had to include the System.XML DLL into my project for this to work for searializing to JSON?? (VS reported the error on line 6 in the example above.) This is an aweful orginization of the standard lib. Why do I need to include System.XML in order to use the JSON serializer?!?!?


Deep breath… Okay, let’s continue.


I used built-in data structures so that the serialization would/should work properly. After all, they are part of the standard lib! So, I would expect the serialized JSON of my data contract to look like:

 1 {
 2   "user_id": 1,
 3   "car_id": 2,
 4   "template_data": {
 5     "key1": "value1",
 6     "key2": "value2",
 7     "key3": "value3"
 8   },
 9   "key": {
10     "key1": "value1",
11     "key2": "value2"
12   }
13 }


Anti-Patern #2 - Write code that doesn’t follow standards or user-expectations

Nope, instead the JSON comes out looking like this:

 1 {
 2   "user_id": 1,
 3   "car_id": 2,
 4   "template_data": [
 5     {"Key": "key1", "Value": "value1"},
 6     {"Key": "key2", "Value": "value2"},
 7     {"Key": "key3", "Value": "value3"}
 8   ],
 9   "key": [
10     {"Key": "key1", "Value": "value1"},
11     {"Key": "key2", "Value": "value2"}
12   ]
13 }

WHAT THE HECK! Who in the world would think a key-value data-structure would translate to an array where each key-value pair is it’s own object!? If that makes any sense to you then, please, explain it to me.


Anti-Pattern #3 - Provide an alternative method that provides the correct functionality, give it a confusing name, and package it with a huge library so that if you only need that one class then you’re screwed.

Come to find out, there is a correct implementation of a JSON serializer that is called JavaScriptSerializer that lives in the System.Web DLL. Okay, if it’s not confusing already that Microsoft is drawing a distinction between JSON and JavaScript serialization, they make sure that if you want proper JSON serialization you have to include the entire System.Web DLL. Seriously!?

I’m just working on a simple utility project that will assist other systems in our infrastructure. This project will be utilized by a variety of project types. I can’t, in good conscience, force every project for carry around a dependency of System.Web. So, off to the interwebs I go to find another solution.



Okay, I’m back and I have a solution! I’m going to rewrite the entire application in Ruby! Yep… That should do the trick.


Anti-Pattern #4 - Make fixing your dumb mistakes require a lot of boiler-plate code that clutters up the user’s code-base.

Ah, if only it were that simple. What I really found on the webs was how to write a wrapper-class to the built-in Dictionary class that would serialize correctly.

 1 [Serializable]
 2 public class JsonDictionary<K, V> : ISerializable
 3 {
 4     Dictionary<K, V> dict = new Dictionary<K, V>();
 5  
 6     public JsonDictionary() { } 
 7  
 8     protected JsonDictionary(SerializationInfo info, StreamingContext context)
 9     {   
10         throw new NotImplementedException();
11     }   
12  
13     public void GetObjectData(SerializationInfo info, StreamingContext context)
14     {   
15         foreach (K key in dict.Keys)
16         {   
17             info.AddValue(key.ToString(), dict[key]);
18         }   
19     }   
20  
21     public void Add(K key, V value)
22     {   
23         dict.Add(key, value);
24     }   
25  
26     public V this[K index]
27     {   
28         set { dict[index] = value; }
29         get { return dict[index]; }
30     }   
31 }

This class just uses a Dictionary as the underlying data-store and serializes correctly. The downside is that it really hides a lot of functionality that is given by the built-in Dictionary type. One really useful feature it is missing is the collections-constructor:

1 var dict = new Dictionary<String, Int32>
2 {
3     {"one",   1 },
4     {"two",   2 },
5     {"three", 3 },
6     // ...
7     {"ten",   10}
8 };

Well, I just can’t do without those nicities. That’s an easy fix though, I just need to be able to call a method, such as ToJson(), on a Dictionary object.

 1 public static class IDictionaryExtension
 2 {
 3     public static JsonDictionary<K, V> ToJsonDictionary<K,V>(this IDictionary<K, V> dict)
 4     {   
 5         if (dict == null)
 6             return null;
 7         var jsonDict = new JsonDictionary<K, V>();
 8         foreach (var key in dict.Keys)
 9         {   
10             jsonDict[key] = dict[key];
11         }   
12         return jsonDict;
13     }                                                                                                                                                                            
14 }

There we go, now I can just call ToJsonDictionary() on any IDictionary object right before serializing to JSON. Finally, we have working serialization!

Step 3 - Send JSON via HTTP POST

In terms of length and complexity, sending a request isn’t too cumbersome of a process. Assuming that we have already serialized the JSON into a Stream object, sending our request looks like the following:

1 WebRequest request = WebRequest.Create(NSUrl);
2 request.Method = "POST";
3 request.ContentLength = jsonStream.Length;
4 request.ContentType = "application/json";
5 Stream requestStream = request.GetRequestStream();
6 requestStream.Write(jsonStream.ToArray(), 0, (int)jsonStream.Length);
7 requestStream.Close();

If we look back at the Ruby example above, you’ll notice that almost all of the code is focusing on sending the request. So, as far as sending web-requests is concerned, the .NET version is comparable in terms of length.

However, one thing to think about—when is the request sent? Well, in this case, it wasn’t. Yep, you read correctly, the request in the above example was never made. You might say, “Of course it never sent, you obviously have to call some type of Send() method or something similar.” Well, that would be the sensible thing to do now wouldn’t it.


Anti-Pattern #5 - Implicit is better than explicit (especially when it is non-obvious)

The request is sent when you ask for the response. Yes, that does make sense if I am interested in the response. However, if I just want to “send and forget” then you would use the following to make the request:

1 // Build up request
2 // ...
3  
4 // Send request
5 request.GetResponse();

Sure… that’s real intuitive.

Step 4 - Verify the response status code

Finally! We’ve made sense of the .NET framework (oxymoron?) and can finally verify the reponse status code. This part is so simple, it’d be a real challenge to screw this one up. It is simply:

1 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
2 var statusCode = response.StatusCode;
3  
4 return statusCode == HttpStatusCode.OK;



Closing Thoughts

Holy crap Microsoft…