您好我和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一些属性用于序列化而不是创建新类来执行此操作 我该怎么办???
答案 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"
}]