views:

249

answers:

1

I have a flattened JSON:

{
    "CaseName" : "John Doe v. State",
    "CaseDate" : "<some date>",
    "Client.FirstName" : "John",
    "Client.LastName" : "Doe",
    "Client.Email" : "[email protected]"
    etc...
}

I want to deserialize it back to this entity:

public class Case()
{
    public string CaseName { get; set; }
    public string CaseDate { get; set; }
    public Client Client { get; set; }
}

where Client.FirstName, Client.LastName, and Client.Email are properties in the Client object. Using Json.NET, is there any way to get it to parse the dot notation and deserialize this entity correctly? Currently, using the default settings, it tells me that Client.FirstName is not a property in type Case.

+1  A: 

Yes, you can. You would derive a class from JsonConverter and override the CanConvert method to indicae that you can convert the Client type.

Then, you would override the ReadJson and WriteJson methods to read and write the fields of the JSON literal.

For a JSON literal like this, it's more than likely you will need to create a JsonConverter for the Case type, as you will need to cache all the properties of the Client object during serialization until you have enough information to actually create the Client instance.

Then, you would call the Add method on the JsonConverterCollection instance exposed by the Converters property on the JsonSerializer instance you are using to perform your serialization/deserialization.

Note that if you need to do this for a number of different classes that might be represented in this manner, then you can write one JsonConverter implementation, and have it scan for an attribute on the property. If the property has the attribute and exposes another object with properties, it would expect to read/write the dot-notation.

It should be noted that while you are using the dot-notation for the identifier, it's very uncommon to do so. If possible, on the side that is constructing the JSON literal, it should be doing it in this manner:

{ 
    CaseName: "John Doe v. State", 
    CaseDate: "<some date>", 
    Client: 
    {
        FirstName: "John", 
        LastName: "Doe", 
        Email: "[email protected]"
    }
} 

But that's assuming that you have control over that end. If you don't, then there's not much you can do.

If you do have control, then constructing your JSON literals in that manner would negate the need for a custom JsonConverter implementation.

casperOne
Yes, I would prefer to convert it correctly on the sender's side (ExtJS), but I'm not sure if that's possible yet. The solution you provided is workable, but too much work given the number of entities and complexity of my object graph. I was hoping for a simple flag or a more generic JsonConverter that would apply for all dot notation properties.
Daniel T.
@Daniel T.: Unfortunately, the JSON is non-standard, which is why Json.NET has problems with it. However, I've added a paragraph to the answer to indicate how you can write *one* JsonConverter implementation, combined with an attribute to tell it to read/write dot-notation when expected.
casperOne