So here's my situation. I'm implementing a WEB API in a WebForms app. I have a bunch of dynamic classes which are essentially dictionaries that need to use a custom JSON serialization formatter in order to work properly (because the default converter simply shows a mess of Key Value pairings).
So first I created a custom JSON converter:
/// <summary>
/// A class to convert entities to JSON
/// </summary>
public class EntityJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsSubclassOf(typeof(Entity));
}
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// Details not important. This code is called and works perfectly.
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Details not important. This code is *never* called for some reason.
}
}
Once I have that defined I then insert it into the global JSON media type formatter:
// Add a custom converter for Entities.
foreach (var formatter in GlobalConfiguration.Configuration.Formatters)
{
var jsonFormatter = formatter as JsonMediaTypeFormatter;
if (jsonFormatter == null)
continue;
jsonFormatter.SerializerSettings.Converters.Add(new EntityJsonConverter());
}
And lastly, my test API (there will be many more added in the future, I'm just trying to test out the system for now, "Contact" inherits from "Entity"):
public class ContactController : ApiController
{
public IEnumerable<Contact> Get()
{
// Details not important. Works perfectly.
}
[HttpPost]
public bool Update(Contact contact)
{
// Details not important. Contact is always "null".
}
}
So here's what I'm seeing when I debug:
Web Site Calls "get":
- Controller.Get is called. Returns list of Contacts.
- Converter.CanConvert is called for the enumeration type. Returns false.
- Converter.CanConvert is called for the Contact type. Returns true.
- Converter.CanWrite is called. Returns true.
- Converter.WriteJson is called. Writes the proper JSON to the stream
- Website receives the proper JSON and is able to use it as an object.
Web Site Calls "update":
- Converter.CanConvert is called for the Contact type. Returns true.
- Controller.Update is called. "contact" parameter is "null".
I'm utterly perplexed. I don't understand why this works when serializing, but the entire process seems to just skip my custom converter when trying to deserialize. Anyone have any ideas what I'm doing wrong?
Thanks!