使用json.net序列化对象并使用jsonignore

时间:2017-08-29 17:55:59

标签: c# json api asp.net-web-api

您好我和JSON有问题。

在Json.Net中,我们应该有一个类来序列化类

的对象

当我有多个类并且类有一些属性时,我喜欢列出一个这样的类:

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

它应该是:

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

但是,当我有两个类,并且我喜欢这两个具有特定属性的类的列表时,我应该创建一个具有两个类的prpperty的类,如:

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);
    }
}

你知道这两个类的所有属性都是serealise但我喜欢toignore一些属性用于序列化而不是创建新类来执行此操作 我该怎么办???

3 个答案:

答案 0 :(得分:1)

我试图理解这个问题。起初我以为它是关于在序列化期间忽略字段。但在阅读你的评论后,我认为这不是问题。

如果我没有弄错,那么你想序列化一个混合类的列表(test和test1)。目前,您正在使用对象(local1)来包装两个列表。但你想要的是一个列表(有或没有对象包装)。如果我错了,请纠正我。

我原来的答案中的方法序列化为一个列表,但不是一个类的混合。因此,您无法将其还原为混合类列表,因为您没有这些信息。所有的都是容器类。

所以你需要的是混合类和维护类信息。

为此您可以使用界面:

public interface baseClass
{
}

在两个类中实现接口:

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; }
}

并创建列表:

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

现在您需要强制序列化程序添加类型信息,但仅在必要时:

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

s返回的内容如下:

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

可以将其反序列化为混合类列表。

这就是你想要的吗?

- 原始答案 -

您可以使用System.ComponentModel.DefaultValueAttribute。这适用于xml和json。

这个想法是序列化输出中省略了具有默认值的属性。这将允许您为不同目的自定义输出,而无需为每个差异创建新模型。在反序列化时,应使用默认值恢复省略的字段。

该值必须与默认值匹配才能被省略。这就是你必须分配默认值的原因。

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

    public string name { get; set; }

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

请注意,name = null和lname = null的结果是相同的。两者都没有序列化。如果为0,则省略id。在反序列化id上将具有值0,恰好是默认值(int)。

要在Json格式化程序配置中设置此工作:

DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate

在序列化对象时,忽略成员值与成员的默认值相同的成员,并在反序列化时将成员设置为默认值。

使用方法:

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

为了省略lname,请跳过以下字段:

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

答案 1 :(得分:0)

您可以使用DefaultContractResolver自定义您要忽略的属性:

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;
    }
}

用法:

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));

答案 2 :(得分:0)

您可以忽略任何财产 只需标记:

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);

结果:

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