簡體   English   中英

使用json.net序列化對象並使用jsonignore

[英]serialize object with json.net and use jsonignore

您好,我和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 };
}

但是,例如,當我有兩個類並且希望擁有具有特定屬性的這兩個類的列表時,我應該創建一個具有兩個類的特性的類:

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

而且您知道這兩個類的所有屬性都是固定的,但是我想忽略一些要序列化的屬性,而不是為此創建新類,我該怎么辦?

我試圖理解這個問題。 起初,我認為這是有關在序列化過程中忽略字段的信息。 但是在閱讀您的評論后,我認為這不是問題。

如果我沒記錯的話,您想序列化一個混合了類(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,恰好是default(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"
    } };
}

您可以使用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));

您可以忽略任何屬性。
只需標記一下:

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"
}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM