RestSharp Custom Serialization with DataContractJsonSerializer for Windows Phone 7

Posted by: | Technical |

We love Restsharp, it cuts out a chunk of boring plumbing code when working with rest services on Windows Phone 7 (WP7) with Json. However, the default JsonDeserializer has a couple of drawbacks:

  1. It doesn’t allow you to use custom attributes on your classes, likeĀ [DataMember(Name = "id")], so if you have very small 2 letter codes for all your json fields, this makes your C# a little bit messy and hard to fathom
  2. It doesn’t seem to deserialize ObservableCollection<T>, throwing an exception if you use this type, List<T> is fine. We wanted to have a single collection type on our App’s model and use this directly for binding.

However, RestSharp is pretty well architected and allows you to swap in your own implementation of its IDeserializer interface. An example of creating the RestClient and making sure our custom deserializer is used is given here:


 private RestClient GetRestClient()
        {
            RestClient client = new RestClient();
            client.AddHandler("application/json", new RestSharpDataContractJsonDeserializer());
            return client;
        }

We found the core .Net DataContractJsonSerializer worked for us really well. The example below shows the implementation where it performs the core deserialization. Note that some of the RestSharp properties are just not used by us so these haven’t been implemented (probably best to throw a NotSupportedException here;).


 public class RestSharpDataContractJsonDeserializer : IDeserializer
    {
        public string RootElement { get; set; }
        public string Namespace { get; set; }
        public string DateFormat { get; set; }
        public CultureInfo Culture { get; set; }

        public RestSharpDataContractJsonDeserializer()
        {
            Culture = CultureInfo.InvariantCulture;
        }

        public T Deserialize(RestResponse response) where T : new()
        {
            T target = new T();
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(response.Content));
            DataContractJsonSerializer ser = new DataContractJsonSerializer(target.GetType());
            target = (T)ser.ReadObject(ms);
            ms.Close();
            return target;
        }

    }

On the flip side, it’s equally possible to have a custom Serializer which is passed as a property of the core RestRequest object for converting your C# types to Json.

An example custom serializer again using the inbuilt .Net DataContractJson Serializer is presented below:


	public class RestSharpDataContractJsonSerializer : ISerializer
	{

		public JsonSerializer() {
			ContentType = "application/json";
		}

		///
		/// Serialize the object as JSON
		///
		/// <param name="obj" />Object to serialize
		/// JSON as String
		public string Serialize(object obj) {
			 //Create a stream to serialize the object to.
            MemoryStream ms = new MemoryStream();

            // Serializer the User object to the stream.
            DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
            ser.WriteObject(ms, obj);
            byte[] json = ms.ToArray();
            ms.Close();
            return Encoding.UTF8.GetString(json, 0, json.Length);
		}

		///
		/// Unused for JSON Serialization
		///
		public string DateFormat { get; set; }
		///
		/// Unused for JSON Serialization
		///
		public string RootElement { get; set; }
		///
		/// Unused for JSON Serialization
		///
		public string Namespace { get; set; }
		///
		/// Content type for serialized content
		///
		public string ContentType { get; set; }
	}