Chr*_*rie 29 c# serialization json.net
给定一个数据模型:
[DataContract]
public class Parent
{
[DataMember]
public IEnumerable<ChildId> Children { get; set; }
}
[DataContract]
public class ChildId
{
[DataMember]
public string Id { get; set; }
}
[DataContract]
public class ChildDetail : ChildId
{
[DataMember]
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
出于实现方便的原因,有时候ChildId对象Parent实际上是ChildDetail对象.当我使用JSON.net来序列化时Parent,它们会被写出所有ChildDetail属性.
是否有任何方法可以指示JSON.net(或任何其他JSON序列化程序,我还没有足够的提交到项目中)在序列化为基类时忽略派生类属性?
编辑:重要的是,当我直接序列化派生类时,我能够生成所有属性.我只想抑制Parent对象中的多态性.
Jas*_*tts 31
我使用自定义合约解析器来限制我的哪些属性要序列化.这可能会指向正确的方向.
例如
/// <summary>
/// json.net serializes ALL properties of a class by default
/// this class will tell json.net to only serialize properties if they MATCH
/// the list of valid columns passed through the querystring to criteria object
/// </summary>
public class CriteriaContractResolver<T> : DefaultContractResolver
{
List<string> _properties;
public CriteriaContractResolver(List<string> properties)
{
_properties = properties
}
protected override IList<JsonProperty> CreateProperties(
JsonObjectContract contract)
{
IList<JsonProperty> filtered = new List<JsonProperty>();
foreach (JsonProperty p in base.CreateProperties(contract))
if(_properties.Contains(p.PropertyName))
filtered.Add(p);
return filtered;
}
}
Run Code Online (Sandbox Code Playgroud)
在覆盖IList函数中,您可以使用反射来填充列表,可能只包含父属性.
合同解析程序适用于您的json.net序列化程序.这个例子来自asp.net mvc应用程序.
JsonNetResult result = new JsonNetResult();
result.Formatting = Formatting.Indented;
result.SerializerSettings.ContractResolver =
new CriteriaContractResolver<T>(Criteria);
Run Code Online (Sandbox Code Playgroud)
Akk*_*kku 21
我有完全相同的问题,并查找如何构建我实际上正在寻找的ContractResolver,并更好地回答这个问题.这只序列化了你想要序列化的Type T的属性,但是通过这个例子你也可以轻松地构建类似的方法:
public class TypeOnlyContractResolver<T> : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
property.ShouldSerialize = instance => property.DeclaringType == typeof (T);
return property;
}
}
Run Code Online (Sandbox Code Playgroud)
遇到了类似的问题,这是ContractResolver我想出的:
public class StrictTypeContractResolver : DefaultContractResolver
{
private readonly Type _targetType;
public StrictTypeContractResolver( Type targetType ) => _targetType = targetType;
protected override IList<JsonProperty> CreateProperties( Type type, MemberSerialization memberSerialization )
=> base.CreateProperties
(
_targetType.IsAssignableFrom( type ) ? _targetType : type,
memberSerialization
);
}
Run Code Online (Sandbox Code Playgroud)
它仅切断targetType的后代的属性,而不会影响其基类或 其targetType属性可能引用的其他类型的属性。根据您的需要,其中可能会或可能不会比当时此处提供的其他答案有所改进。
我没有特别使用过 JSON.Net,所以不确定这会对你有帮助。如果 JSON.Net 派生自 .Net 序列化系统,那么您应该能够将 [NonSerialized] 属性添加到您现在希望在基类中序列化的属性。当您调用基类上的序列化方法时,序列化应跳过这些元素。
| 归档时间: |
|
| 查看次数: |
22765 次 |
| 最近记录: |