Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ignore JsonProperty(PropertyName = "someName") when serializing json?

I have some C# code using ASP.Net MVC, which is making use of Json.Net to serialize some DTOs. In order to reduce payload, I have made use of the [JsonProperty(PropertyName = "shortName")] attribute to use shorter property names during serialization.

This works great when the client is another .Net app or service, as the deserialization puts the object hierarchy back together, using the longer more friendly names, while keeping actual transfer payload low.

The problem comes into play when the client is javascript/ajax through a browser. It makes the request, and gets the json ... but that json is using the shortened less-friendly names.

How can I make the json.net serialization engine ignore the [JsonProperty(PropertyName = "shortName")] attribute programmatically? Ideally, my MVC service is going to sit there running and normally serialize using the shortened property names. When my code detects a particular parameter, I'd like to get the data serialized using the longer names and ignore the [JsonProperty()] attribute.

Any suggestions?

Thanks,

Kevin

like image 788
Kevin Avatar asked Dec 16 '13 22:12

Kevin


People also ask

Is JSON serialized or Deserialized?

JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object). If you serialize this result it will generate a text with the structure and the record returned.

What is JsonSerializerSettings?

Specifies the settings on a JsonSerializer object. Newtonsoft.Json. JsonSerializerSettings. Namespace: Newtonsoft.Json.

What is JsonProperty attribute?

JsonPropertyAttribute indicates that a property should be serialized when member serialization is set to opt-in. It includes non-public properties in serialization and deserialization. It can be used to customize type name, reference, null, and default value handling for the property value.


2 Answers

This can be done pretty easily using a custom contract resolver. Here's all the code you would need:

class LongNameContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        // Let the base class create all the JsonProperties 
        // using the short names
        IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);

        // Now inspect each property and replace the 
        // short name with the real property name
        foreach (JsonProperty prop in list)
        {
            prop.PropertyName = prop.UnderlyingName;
        }

        return list;
    }
}

Here's a quick demo using the resolver:

class Program
{
    static void Main(string[] args)
    {
        Foo foo = new Foo
        {
            CustomerName = "Bubba Gump Shrimp Company",
            CustomerNumber = "BG60938"
        };

        Console.WriteLine("--- Using JsonProperty names ---");
        Console.WriteLine(Serialize(foo, false));
        Console.WriteLine();
        Console.WriteLine("--- Ignoring JsonProperty names ---");
        Console.WriteLine(Serialize(foo, true));
    }

    static string Serialize(object obj, bool useLongNames)
    {
        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.Formatting = Formatting.Indented;
        if (useLongNames)
        {
            settings.ContractResolver = new LongNameContractResolver();
        }

        return JsonConvert.SerializeObject(obj, settings);
    }
}

class Foo
{
    [JsonProperty("cust-num")]
    public string CustomerNumber { get; set; }
    [JsonProperty("cust-name")]
    public string CustomerName { get; set; }
}

Output:

--- Using JsonProperty names ---
{
  "cust-num": "BG60938",
  "cust-name": "Bubba Gump Shrimp Company"
}

--- Ignoring JsonProperty names ---
{
  "CustomerNumber": "BG60938",
  "CustomerName": "Bubba Gump Shrimp Company"
}
like image 165
Brian Rogers Avatar answered Oct 18 '22 23:10

Brian Rogers


Just want to "extend" Brian's answer with Deserializer class,

static T Deserialize<T>(string json)
{
    return JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings()
    {
        ContractResolver = new LongNameContractResolver()
    });
}
like image 2
Jawad Avatar answered Oct 18 '22 23:10

Jawad