我正在尝试仅使用json.net序列化类的继承属性。我知道[JsonIgnore]属性,但是我只想在某些情况下忽略它们,因此我改用了自定义JsonConverter。
这是我的课:
public class EverythingButBaseJsonConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // Find properties of inherited class var classType = value.GetType(); var classProps = classType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList(); // Remove the overrided properties classProps.RemoveAll(t => { var getMethod = t.GetGetMethod(false); return (getMethod.GetBaseDefinition() != getMethod); }); // Get json data var o = (JObject)JToken.FromObject(value); // Write only properties from inhertied class foreach (var p in o.Properties().Where(p => classProps.Select(t => t.Name).Contains(p.Name))) p.WriteTo(writer); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(""); } public override bool CanRead { get { return false; } } public override bool CanConvert(Type objectType) { return true; } }
做一个简单的o.WriteTo(writer); 它给出的结果与不使用转换器的结果相同。当遍历属性并在属性上使用WriteTo时,它对于基本类型(int,字符串等)正常工作,但是集合存在问题。
预期:
{ "Type": 128, "Time": [ 1, 2, ], "Pattern": 1, "Description": "" }
得到:
"Type": 128, "Time": [ 1, 2, ]"Pattern": 1, "Description": ""
如您所见,该集合缺少“,”和结束行部分。我也缺少整个对象的全局{}。
我在做正确的事情吗?有没有更简单的方法来获得我想要的结果?
不知道为什么您的代码不起作用(可能是Json.NET错误?)。相反,您可以从中删除不需要的属性,JObject并在一个调用中编写整个内容:
JObject
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // Find properties of inherited class var classType = value.GetType(); var classProps = classType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList(); // Remove the overrided properties classProps.RemoveAll(t => { var getMethod = t.GetGetMethod(false); return (getMethod.GetBaseDefinition() != getMethod); }); // Get json data var o = (JObject)JToken.FromObject(value); // Remove all base properties foreach (var p in o.Properties().Where(p => !classProps.Select(t => t.Name).Contains(p.Name)).ToList()) p.Remove(); o.WriteTo(writer); }
另外,您可以创建自己的合同解析器并过滤基本属性和成员:
public class EverythingButBaseContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { if (member.ReflectedType != member.DeclaringType) return null; if (member is PropertyInfo) { var getMethod = ((PropertyInfo)member).GetGetMethod(false); if (getMethod.GetBaseDefinition() != getMethod) return null; } var property = base.CreateProperty(member, memberSerialization); return property; } }
然后像这样使用它:
var settings = new JsonSerializerSettings { ContractResolver = new EverythingButBaseContractResolver() }; var json = JsonConvert.SerializeObject(rootObject, Formatting.Indented, settings);