Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to exclude specific type from json serialization

I am logging all requests to my WCF web services, including the arguments, to the database. This is the way I do it:

  • create a class WcfMethodEntry which derives from PostSharp's aspect OnMethodBoundaryAspect,
  • annotate all WCF methods with WcfMethodEntry attribute,
  • in the WcfMethodEntry I serialize the method arguments to json with the JsonConvert.SerializeObject method and save it to the database.

This works ok, but sometimes the arguments are quite large, for example a custom class with a couple of byte arrays with photo, fingerprint etc. I would like to exclude all those byte array data types from serialization, what would be the best way to do it?

Example of a serialized json:

[
   {
      "SaveCommand":{
         "Id":5,
         "PersonalData":{
            "GenderId":2,
            "NationalityCode":"DEU",
            "FirstName":"John",
            "LastName":"Doe",
         },
         "BiometricAttachments":[
            {
               "BiometricAttachmentTypeId":1,
               "Parameters":null,
               "Content":"large Base64 encoded string"
            }
         ]
      }
   }
]

Desired output:

[
   {
      "SaveCommand":{
         "Id":5,
         "PersonalData":{
            "GenderId":2,
            "NationalityCode":"DEU",
            "FirstName":"John",
            "LastName":"Doe",
         },
         "BiometricAttachments":[
            {
               "BiometricAttachmentTypeId":1,
               "Parameters":null,
               "Content":"..."
            }
         ]
      }
   }
]

Edit: I can't change the classes that are used as arguments for web service methods - that also means that I cannot use JsonIgnore attribute.

like image 561
sventevit Avatar asked Oct 21 '15 11:10

sventevit


People also ask

How do I ignore properties in JSON?

To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.

What is a JSON serialization exception?

The exception thrown when an error occurs during JSON serialization or deserialization.

What is the difference between JSON and serialization?

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 difference between Stringify and serialize?

stringify() ignores functions/methods when serializing. JSON also can't encode circular references. Most other serialization formats have this limitation as well but since JSON looks like javascript syntax some people assume it can do what javascript object literals can.


2 Answers

The following allows you to exclude a specific data-type that you want excluded from the resulting json. It's quite simple to use and implement and was adapted from the link at the bottom.

You can use this as you cant alter the actual classes:

public class DynamicContractResolver : DefaultContractResolver
{

    private Type _typeToIgnore;
    public DynamicContractResolver(Type typeToIgnore)
    {
        _typeToIgnore = typeToIgnore;
    }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);

        properties = properties.Where(p => p.PropertyType != _typeToIgnore).ToList();

        return properties;
    }
}

Usage and sample:

public class MyClass
{
    public string Name { get; set; }
    public byte[] MyBytes1 { get; set; }
    public byte[] MyBytes2 { get; set; }
}

MyClass m = new MyClass
{
    Name = "Test",
    MyBytes1 = System.Text.Encoding.Default.GetBytes("Test1"),
    MyBytes2 = System.Text.Encoding.Default.GetBytes("Test2")
};



JsonConvert.SerializeObject(m, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new DynamicContractResolver(typeof(byte[])) });

Output:

{
  "Name": "Test"
}

More information can be found here:

Reducing Serialized JSON Size

like image 80
Ric Avatar answered Sep 22 '22 14:09

Ric


You could just use [JsonIgnore] for this specific property.

[JsonIgnore]
public Byte[] ByteArray { get; set; }

Otherwise you can also try this: Exclude property from serialization via custom attribute (json.net)

like image 36
Camo Avatar answered Sep 23 '22 14:09

Camo