我们正在运行到上同时与微软JSON序列化和JSON.NET一个MVC3项目的情况。
大家都知道的DateTime的是微软的串行基本上打破,所以我们切换到JSON.NET以避免此问题。 除了一些我们试图序列化类都是波苏斯与DataContract /的DataMember属性,这些属性的伟大工程。 他们在在多个地方引用的程序规定。 此外,它们具有未标记为数据成员为效率一些其它显示属性。 例如,一个客户
[DataContract]
public class Customer
{
[DataMember]
public string FirstName { get; set;}
[DataMember]
public string LastName { get; set;}
public string FullName
{
get
{ return FirstName + " " + LastName; }
}
}
当该客户经过WCF客户端可以引用组装和使用全名就好了,但与JSON.NET连载它看到全名不是一个[DataMember]
并不会对其进行序列化。 有没有传递到JSON.NET告诉它忽略一个类事实的选项[DataContract]
加属性?
注意:使用.NET中的JavaScriptSerializer工作正常FullName属性,但DateTime是否被破坏。 我需要JSON.NET忽略这一类有DataContract /的DataMember属性的事实,只是做普通的公开领域系列化就像它将如果他们不存在。
只需使用Json.Net的选择禁用属性。 这将优先于DataContract。
[DataContract]
[JsonObject(MemberSerialization.OptOut)]
正如Amry说,你可以使用你自己的IContractResolver。
不幸的是由Amry提供的解决方案,我没有工作,下面是我设法获得工作的解决方案:
public class AllPropertiesResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
//property.HasMemberAttribute = true;
property.Ignored = false;
//property.ShouldSerialize = instance =>
//{
// return true;
//};
return property;
}
}
有评论说几行,这些wern't要求使我的解决方案的工作,但你永远不知道!
这有相同的使用作为Amry的解决方案:
var json = JsonConvert.SerializeObject(result, new JsonSerializerSettings {
ContractResolver = new AllPropertiesResolver()
});
希望这可以帮助!
我有几乎涉及您遇到什么问题,并设法找到通过Json.NET的代码去解决。 因此,它可能不是最好的解决办法,但它为我工作。
要做到这一点,你需要实现自己的IContractResolver
。 这方面的一个过于简单的实现,包括所有的参数,并忽略所有属性(不只是DataContract
,但其他内置Json.NET的规则一样,所以无论你选择设置本来应该影响到会员选择现在正由该代码overidden ):
class AllPropertiesResolver : DefaultContractResolver
{
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
return objectType.GetProperties()
.Where(p => p.GetIndexParameters().Length == 0)
.Cast<MemberInfo>()
.ToList();
}
}
这里谈到的代码使用示例:
var json = JsonConvert.SerializeObject(result, new JsonSerializerSettings {
ContractResolver = new AllPropertiesResolver()
});
如果你想忽略的存在DataContractAttribute
所有类型,而不必增加额外的属性,那么定制合同解析器是正确的解决方案。 然而,随着Json.NET的9.0.1 Amry的解析器不再起作用。 Doolali的解析工作,但它具有序列化的所有公共属性,包括那些标有额外的副作用[JsonIgnore]
如果你需要一个合同解析器, 只有忽略的存在DataContractAttribute
但其他行为类似于默认的合同解析器中,可以使用下列:
public class IgnoreDataContractContractResolver : DefaultContractResolver
{
static MemberSerialization RemoveDataContractAttributeMemberSerialization(Type type, MemberSerialization memberSerialization)
{
if (memberSerialization == MemberSerialization.OptIn)
{
type = Nullable.GetUnderlyingType(type) ?? type;
// Json.NET interprets DataContractAttribute as inherited despite the fact it is marked with Inherited = false
// https://json.codeplex.com/discussions/357850
// https://stackoverflow.com/questions/8555089/datacontract-and-inheritance
// https://github.com/JamesNK/Newtonsoft.Json/issues/603
// Thus we need to manually climb the type hierarchy to see if one is present.
var dataContractAttribute = type.BaseTypesAndSelf().Select(t => t.GetCustomAttribute<DataContractAttribute>()).FirstOrDefault(a => a != null);
var jsonObjectAttribute = type.GetCustomAttribute<JsonObjectAttribute>();
if (dataContractAttribute != null && jsonObjectAttribute == null)
memberSerialization = MemberSerialization.OptOut;
}
return memberSerialization;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var properties = base.CreateProperties(type, RemoveDataContractAttributeMemberSerialization(type, memberSerialization));
return properties;
}
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
var contract = base.CreateObjectContract(objectType);
contract.MemberSerialization = RemoveDataContractAttributeMemberSerialization(objectType, contract.MemberSerialization);
return contract;
}
}
public static class TypeExtensions
{
public static IEnumerable<Type> BaseTypesAndSelf(this Type type)
{
while (type != null)
{
yield return type;
type = type.BaseType;
}
}
}
你可能想缓存以获得最佳性能的合同解析器 。
根据到Json.NET文档[DataMember]
如果属性也与Json.NET特定属性(如注释被忽略的属性[JsonProperty]
参见的序列化属性的文档的详细信息:
Json.NET属性接管标准.NET序列化的属性,例如,如果遵和JsonPropertyAttribute都DataMemberAttribute上存在的属性和两个自定义名称,将使用从JsonPropertyAttribute名称。
文档只覆盖了name属性,但我的经验[JsonProperty]
属性也完全阴影在完成设置[DataMember]
属性。 所以,如果这是你的情况下是可行的,还加Json.NET属性为其[数据成员]注释应该被忽略的属性。
您是否尝试过这个?
IgnoreDataMemberAttribute