Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.net serialize only certain properties

Does Json.net have any way to specify only the properties you want to be serialized? or alternatively serialize certain properties based on binding flags like Declared Only?

Right now I am using JObject.FromObject(MainObj.SubObj); to get all properties of SubObj which is an instance of a class that obeys the ISubObject interface:

public interface ISubObject
{

}

public class ParentSubObject : ISubObject
{
    public string A { get; set; }
}


public class SubObjectWithOnlyDeclared : ParentSubObject
{
    [JsonInclude] // This is fake, but what I am wishing existed
    public string B { get; set; }

    [JsonInclude] // This is fake, but what I am wishing existed
    public string C { get; set; }
}

public class NormalSubObject: ParentSubObject
{
    public string B { get; set; }
}

If MainObj.SubObj was a NormalSubObject it would serailize both A and B but if it was SubObjectWithOnlyDeclared it would serailize only B and C and ignore the parent property

like image 814
CuriousDeveloper Avatar asked Jun 21 '18 17:06

CuriousDeveloper


People also ask

How do you exclude properties from JSON deserialization?

To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property.

How can you prevent a property from being serialized?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.

Does JSON net serialize private fields?

So yes, it will serialize private fields if you mark them with [SerializeField] attribute.

Can I optionally turn off the JsonIgnore attribute at runtime?

Yes, this can be done using a custom ContractResolver . You didn't show any code, so I'll just make up an example. Let's say I have a class Foo as shown below.


3 Answers

Rather then having to use [JsonIgnore] on every attribtue you don't want to serialise as suggested in another answer.

If you just want to specify properties to serialise, you can do this, using [JsonObject(MemberSerialization.OptIn)] and [JsonProperty] attributes, like so:

using Newtonsoft.Json;
...
[JsonObject(MemberSerialization.OptIn)]
public class Class1
{
    [JsonProperty]
    public string Property1 { set; get; }
    public string Property2 { set; get; }
}

Here only Property1 would be serialised.

like image 99
Alfie Avatar answered Oct 03 '22 02:10

Alfie


You can write a custom ContractResolver like below

public class IgnoreParentPropertiesResolver : DefaultContractResolver
{
    bool IgnoreBase = false;
    public IgnoreParentPropertiesResolver(bool ignoreBase)
    {
        IgnoreBase = ignoreBase;
    }
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var allProps = base.CreateProperties(type, memberSerialization);
        if (!IgnoreBase) return allProps;

        //Choose the properties you want to serialize/deserialize
        var props = type.GetProperties(~BindingFlags.FlattenHierarchy); 

        return allProps.Where(p => props.Any(a => a.Name == p.PropertyName)).ToList();
    }
}

Now you can use it in your serialization process as:

var settings = new JsonSerializerSettings() { 
                      ContractResolver = new IgnoreParentPropertiesResolver(true) 
               };
var json1 = JsonConvert.SerializeObject(new SubObjectWithOnlyDeclared(),settings );
like image 37
Eser Avatar answered Oct 03 '22 00:10

Eser


If you have a property on your object that is null or the default value, you can let json.net ignore it and NOT serialize it by:

var settings = new JsonSerializerSettings 
{
    DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore
};

JsonConvert.SerializeObject(myObject, settings);

EDIT:

Or global default setting, do this once:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings 
{
    DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore
};
like image 41
Atif Rehman Avatar answered Oct 03 '22 01:10

Atif Rehman