amir jahany
amir jahany

Reputation: 45

serialize object with json.net and use jsonignore

Hello I have a problem with and JSON. 

 in Json.Net we should have a class to serialize the object of class 

 when I have multiple classes and the classes have some properties and I like to have a list one class like this:

public class test
{
    public int id { get; set; }
    public string name { get; set; }
    public string lname { get; set; }
}

 

 it should be:

public List<test> get()
{
    test t = new test();
    t.id = 2;
    t.lname = "jahany";
    t.name = "amir";
    return new List<test>() { t };
}

   but when I have for example two classes  and I like to have list of these two classes with a specific properties  I should have created one class  that have prpperty of two classes like:

public class test1
{
    public int id { get; set; }
    public string name { get; set; }
}


public class local1
{
    List<test> lst1;
    List<test1> lst2;
    public List<local1> get()
    {
        local1 l = new local1();
        test t = new test();
        t.id = 2;
        t.lname="jahany"
        test1 t1 = new test1();
        t1.name = "amir";
        t.id = 123;
        l.lst1.Add(t);
        l.lst2.Add(t1);
        return new List<local1>(l);
    }
}

 

And you know all the properties of the two classes is  serealise  but I like toignore some property for serialize  and not create new class for do this what can i do???

Upvotes: 0

Views: 519

Answers (3)

user4864425
user4864425

Reputation:

I am trying to understand the question. At first I thought it was about ignoring fields during serialization. But after reading your comment I don't think that's the question.

If I am not mistaken then you want to serialize one list which is a mix of classes (test and test1). At the moment you are using an object (local1) to wrap the two lists. But what you want is one list (with or without the object wrapper). Please correct me if I'm wrong.

The method from my original answer serializes as one list, but not as a mix of classes. So you cannot restore it to a list of mixed classes, because you don't have the information. All there is, is the container class.

So what you need is something to mix the classes and maintain the class information.

For this you can use an interface:

public interface baseClass
{
}

Implement the interface in the two classes:

public class test : baseClass
{
    public int id { get; set; }
    public string name { get; set; }
    public string lname { get; set; }
}

public class test1 : baseClass
{
    public int id { get; set; }
    public string name { get; set; }
}

And create the list:

var lst = new List<baseClass>();
lst.Add(new test { id = 2, lname = "jahany" });
lst.Add(new test1 { name = "amir", id = 123 });

And now you'll need to force the serializer to add type information, but only when necessary:

var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
var s = JsonConvert.SerializeObject(lst, settings);

Where s returns something like:

[
    {"$type":"test","id":2,"name":null,"lname":"jahany"},
    {"$type":"test1","id":123,"name":"amir"}
]

Which can be deserialized into a list of mixed classes.

Is this what you are after?

-- original answer --

You can use System.ComponentModel.DefaultValueAttribute. This works for both xml and json.

The idea is that properties with a default value are omitted from the serialized output. That will allow you to customize the output for different purposes without having to create a new model for every difference. On deserialization the omitted fields should be restored with the default value.

The value has to match the default value in order to be omitted. That is why you actually have to assign a default value.

public class test
{
    [DefaultValue(0)]
    public int id { get; set; } = 0;

    public string name { get; set; }

    [DefaultValue(null)]
    public string lname { get; set; } = null;
}

Please note that the result of name=null and lname=null is the same. Both are not serialized. Also id is omitted if 0. On deserialization id will have the value 0, which happens to be default(int).

To make this work set in the Json formatter configuration:

DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate

This will ignore members where the member value is the same as the member's default value when serializing objects and set members to their default value when deserializing.

How to use:

public List<test> get()
{
    return new List<test>() { new test
    {
        id = 2,
        lname = "jahany",
        name = "amir"
    } };
}

In order to omit lname just skip the field:

public List<test> get2()
{
    return new List<test>() { new test
    {
        id = 2,
        //lname = "jahany",
        name = "amir"
    } };
}

Upvotes: 1

MakS
MakS

Reputation: 131

You can ignore any property.
Just mark it:

public class test
{
    public int id { get; set; }
    public string name { get; set; }
    public virtual string lname { get; set; }
}
public class test1 : test
{
  [JsonIgnore]
  public override string lname { get; set; }
}
var list = new List<test>()
{
   new test() {id = 1, name = "name1", lname = "lname1"},
   new test1() {id = 2, name = "name2", lname = "lname2"}
};
var s = JsonConvert.SerializeObject(list);

Result:

[{
    "id": 1,
    "name": "name1",
    "lname": "lname1"
}, {
    "id": 2,
    "name": "name2"
}]

Upvotes: 0

Xiaoy312
Xiaoy312

Reputation: 14477

You can use DefaultContractResolver customize which property you want to ignore:

public class IgnorePropertiesContractResolver<T> : DefaultContractResolver
{
    private IReadOnlyList<string> ignoredProperties;

    public IgnorePropertiesContractResolver(params string[] properties)
    {
        ignoredProperties = properties.ToList();
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        if (member.DeclaringType == typeof(T) && ignoredProperties.Contains(member.Name))
        {
            property.Ignored = true;
        }

        return property;
    }
}

Usage:

var json1 = "{id: 1, name: 'qwe', lname: 'qwe'}";
var json2 = "{id: 2, name: 'asd', lname: 'asd'}";


var ignoreLName = new JsonSerializerSettings
{
     ContractResolver = new IgnorePropertiesContractResolver<test>("lname")
};

var tests = new List<test>();
tests.Add(JsonConvert.DeserializeObject<test>(json1));
tests.Add(JsonConvert.DeserializeObject<test>(json2, ignoreLName));

Upvotes: 0

Related Questions