我的情况是这样的。我们正处在决定使用哪种Json序列化工具的关键时刻。我们正在考虑Newtonsoft。JSON和Microsoft JavaScriptSerializer。Newtonsoft。JSON是我们的第一次尝试,但是我们发现了一些奇怪的行为。下面是示意图代码来说明这个问题。假设我们有如下的类配置:
interface IA<T>
{
T Id { get; set; }
}
[DataContractAttribute]
abstract class A : IA<string>
{
protected A() { }
[DataMemberAttribute]
public virtual string Id
{
get;
set;
}
}
class B : A
{
public string P1 { get; set; }
public string P2 { get; set; }
}
如果我们将使用Newtonsoft。Json的JsonConvert类从B类中获取Json字符串,我们可以使用以下代码:
B b = new B();
string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(b,
new Newtonsoft.Json.JsonSerializerSettings() {
NullValueHandling = Newtonsoft.Json.NullValueHandling.Include
});
但不幸的是,只有Id属性会反映在结果JSON字符串中。B类的所有其他属性都不会显示出来。相反,JavaScriptSerializer会像预期的那样生成JSON字符串。类B是我们的类,类A和接口IA来自第三方库,所以我们不能修改。此外,我们也不想在我们的类上使用数据契约序列化注释,只是为了安抚挑剔的json序列化器。
是否有办法指示Newtonsoft.Json.JsonConvert序列化所有属性,无论是否有注释?
编辑:虽然@LB提供了可接受的答案,@dbc提出了更全面的解决方案,所以如果你想看到它,只需跟随他提供的链接作为这个问题的副本。
Json不需要DataContractAttribute
和DataMemberAttribute
。网删除它们,你的代码就可以工作了....
要么在所有属性中使用它们,要么不使用它们
见http://www.newtonsoft.com/json/help/html/DataContractAndDataMember.htm
——编辑——
如果你不想使用任何Attributes
,那么你可以创建一个自定义的ContractResolver
public class MyDefaultContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var result = base.CreateProperties(type, memberSerialization).ToList();
result.ForEach(x => { x.Ignored = false; }); // <-- Include or not?
return result;
}
}
并将代码序列化为:
string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(b,
new Newtonsoft.Json.JsonSerializerSettings()
{
NullValueHandling = Newtonsoft.Json.NullValueHandling.Include,
ContractResolver = new MyDefaultContractResolver()
});