Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET - prevent re-serializing an already-serialized property [duplicate]

In an ASP.NET Web API application, some of the models I'm working with contain a chunk of ad-hoc JSON that is useful only on the client side. On the server it simply goes in and out of a relational database as a string. Performance is key, and it seems pointless to process the JSON string server side at all.

So in C#, imagine an object like this:

new Person
{
    FirstName = "John",
    LastName = "Smith",
    Json = "{ \"Age\": 30 }"
};

By default, Json.NET will serialize this object like this:

{
    "FirstName": "John",
    "LastName": "Smith",
    "Json": "{ \"Age\": 30 }"
}

I'd like to be able to instruct Json.NET to assume that the Json property is already a serialized representation, thus it shouldn't re-serialize, and the resulting JSON should look like this:

{
    "FirstName": "John",
    "LastName": "Smith",
    "Json": {
        "Age": 30
    }
}

Ideally this works in both directions, i.e. when POSTing the JSON representation it will automatically deserialize to the C# representation above.

What is the best mechanism to achieve this with Json.NET? Do I need a custom JsonConverter? Is there a simpler attribute-based mechanism? Efficiency matters; the whole point is to skip the serialization overhead, which could be a bit of a micro-optimization, but for argument's sake let's assume it's not. (There will potentially be big lists with bulky Json properties being returned.)

like image 762
Todd Menier Avatar asked Sep 29 '15 17:09

Todd Menier


1 Answers

If you are able to change the type of the Json property on Person from string to JRaw then you will get the desired result.

public class Person
{
    public string FirstName { get; set;}
    public string LastName { get; set;}        
    public JRaw Json  { get; set;}
} 

Alternatively, you could keep the string property, and add a JRaw property to be used as a proxy for serialization:

public class Person
{
    public string FirstName { get; set;}
    public string LastName { get; set;}
    [JsonIgnore]
    public string Json { get; set; }

    [JsonProperty("Json")]
    private JRaw MyJson
    {
        get { return new JRaw(this.Json); }
        set { this.Json = value.ToString(); }
    }        
}

Either way, both serialization and deserialization will work as you have requested.

like image 193
Mike Hixson Avatar answered Oct 11 '22 01:10

Mike Hixson