反序列化期间JSON.Net忽略属性

我有一个课程设置如下:

public class Foo { public string string1 { get; set; } public string string2 { get; set; } public string string3 { get; set; } } 

我使用Json.Net反序列化以下Json响应:

 string json = "[{\"number1\": 1, \"number2\": 12345678901234567890, \"number3\": 3}, {\"number1\": 9, \"number2\": 12345678901234567890, \"number3\": 8}]"; 

反序列化代码:

 List foos = JsonConvert.DeserializeObject<List>(json); 

第二个数字超过int-64,但我并不真正关心检索该值。 有没有办法将’number2’属性转换为字符串,或者在反序列化期间完全忽略它?

我尝试将'[JsonConverter(typeof(string))]属性添加到string2属性,但收到错误:’创建System.String时出错’。 我也试过设置typeof(十进制)。

我也试过使用[JsonIgnore],但这不起作用。

您可以使用JsonSerializerSettings对象的MissingMemberHandling属性。

用法示例:

 var jsonSerializerSettings = new JsonSerializerSettings(); jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore; JsonConvert.DeserializeObject(jsonResponse, jsonSerializerSettings); 

更多信息在这里 。

这是一个蹩脚的解决方法,但您可以创建一个方法来手动加载json。 如果在没有自动反序列化器的情况下加载太多数据,只需删除您不想要的节点。 但这要慢得多。

 public static List FromJson(string input) { var json = JToken.Parse(input); json["key"].Remove(); var foo = JsonConvert.DeserializeObject>(json.ToString()); } 

这是一个有趣的问题,我想知道是否有人有更好的解决方案。

以下是Newtonsoft Json忽略属性的首选方法,无需根据http://james.newtonking.com/json/help/index.html?topic=html/ReducingSerializedJSONSize.htm修改类。

这个用于忽略EF或Linq2Sql的惰性引用属性

 public class DynamicContractResolver : DefaultContractResolver { protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { Func includeProperty = t => t.IsValueType || t.Namespace.StartsWith("System") && t.Namespace.StartsWith("System.Data")==false; IList properties = base.CreateProperties(type, memberSerialization); var allProperties = properties.Select (p => new{p.PropertyName,Including=includeProperty(p.PropertyType), p.PropertyType});//.Dump("props"); var warnProperties=allProperties.Where (a =>a.Including && a.PropertyType.IsValueType==false && a.PropertyType.Name.IsIgnoreCaseMatch("String")==false) ; //linq pad debugging helper //var propertyTypesSerializing= allProperties.Where (p => p.Including).Select (p => p.PropertyType).Distinct().OrderBy (p => p.Name).Dump(); if(warnProperties.Any()) { //LinqPad helper //Util.Highlight(warnProperties.ToArray()).Dump("warning flag raised, aborting"); throw new ArgumentOutOfRangeException(); } properties = properties.Where(p =>includeProperty(p.PropertyType)).ToList(); return properties; } } 

所有.Dump()调用都只是linqpad调试助手,不需要方法调用。

样品用量:

 var inactives = from am in Aspnet_Memberships join mm in Member_members on am.UserId equals mm.Member_guid where mm.Is_active==false && mm.Org_id==1 select new{am,mm}; //inactives.Take(4).ToArray().Dump(); var serialized = JsonConvert.SerializeObject( inactives.Skip(1).Select(i => i.mm).First(), new JsonSerializerSettings() { ContractResolver = new DynamicContractResolver(), PreserveReferencesHandling = PreserveReferencesHandling.None, ReferenceLoopHandling= ReferenceLoopHandling.Ignore }); //.Dump(); 

与@Maslow 的解决方案类似,您可以使用另一个通用的“ignorer” :

 var jsonResolver = new IgnorableSerializerContractResolver(); // ignore your specific property jsonResolver.Ignore(typeof(Foo), "string2"); // ignore single datatype jsonResolver.Ignore(typeof(System.Data.Objects.DataClasses.EntityObject)); var jsonSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, ContractResolver = jsonResolver }; 

添加到drzaus回答:您可以使用他建议的DefaultContractResolver ..只需在其CreateProperty使用property.Ignored = true; 而不是property.ShouldSerialize ,然后当你将JsonSerializerSettings传递给DeserializeObject函数或SerializeObject函数时它是好的。