使用 Newoftoft的JSON (版本8.0.0)为 .Net / C#序列化DependencyObject
派生类时,我注意到它始终序列化{{1 }}和DependencyObjectType
个对象以及我的所有衍生类属性。由于Dispatcher
和DependencyObjectType
对象来自我继承的Dispatcher
类,如何添加智能标记或属性(例如DependencyObject
)以防止它们被序列化?或者我或许是以错误的方式思考它?
示例类代码:
[JsonIgnore]
串行器代码:
public class MyClass : DependencyObject
{
public int MyProperty
{
get { return (int)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0));
}
当序列化时,我得到了这个巨大的blob(除了顶线以外都是不需要的):
JsonSerializer serializer = new JsonSerializer();
using (StreamWriter sw = new StreamWriter(filePath))
using (JsonWriter jw = new JsonTextWriter(sw))
{
serializer.Serialize(jw, MyInstance);
}
答案 0 :(得分:3)
您可以使用 OptIn 方法来禁止类型层次结构中除必需属性之外的所有属性的序列化:
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
使用以下命令标记序列化的属性:
[JsonProperty]
答案 1 :(得分:1)
您可以使用MemberSerialization.OptIn
和[JsonProperty]
标记您的类型,如@Filip's answer中所述。
第二个答案是使用省略指定基类的所有属性或基类集合的custom ContractResolver
:
/// <summary>
/// Contract resolver to ignore properties of a single given type.
/// </summary>
/// <typeparam name="T"></typeparam>
public class IgnoreTypePropertiesContractResolver<T> : IgnoreTypePropertiesContractResolver
{
// As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.
// http://www.newtonsoft.com/json/help/html/ContractResolver.htm
// http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm
// "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."
static IgnoreTypePropertiesContractResolver<T> instance;
static IgnoreTypePropertiesContractResolver() { instance = new IgnoreTypePropertiesContractResolver<T>(); }
public static IgnoreTypePropertiesContractResolver<T> Instance { get { return instance; } }
IgnoreTypePropertiesContractResolver() : base(new[] { typeof(T) }) { }
}
/// <summary>
/// Contract resolver to ignore properties of any number of given types.
/// </summary>
public class IgnoreTypePropertiesContractResolver : DefaultContractResolver
{
readonly HashSet<Type> toIgnore;
readonly HashSet<Type> toIgnoreAndBase;
public IgnoreTypePropertiesContractResolver(IEnumerable<Type> toIgnore)
{
if (toIgnore == null)
throw new ArgumentNullException();
this.toIgnore = new HashSet<Type>(toIgnore);
this.toIgnoreAndBase = new HashSet<Type>(toIgnore.SelectMany(t => t.BaseTypesAndSelf()));
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var list = base.CreateProperties(type, memberSerialization);
if (type.BaseTypesAndSelf().Any(t => toIgnore.Contains(t)))
{
var filtered = list.Where(p => !toIgnoreAndBase.Contains(p.DeclaringType)).ToList();
return filtered;
}
return list;
}
}
public static class TypeExtensions
{
public static IEnumerable<Type> BaseTypesAndSelf(this Type type)
{
while (type != null)
{
yield return type;
type = type.BaseType;
}
}
}
使用自定义合约解析程序,无需为每种类型添加属性。
然后序列化如下:
var settings = new JsonSerializerSettings { ContractResolver = IgnoreTypePropertiesContractResolver<DependencyObject>.Instance };
var json = JsonConvert.SerializeObject(new MyClass { MyProperty = 101 }, settings);