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

FEX*_*OLF 29 c# json json.net

我有一个课程设置如下:

public class Foo
{
    public string string1 { get; set; }
    public string string2 { get; set; }
    public string string3 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

string json = "[{\"number1\": 1, \"number2\": 12345678901234567890, \"number3\": 3},      
{\"number1\": 9, \"number2\": 12345678901234567890, \"number3\": 8}]";
Run Code Online (Sandbox Code Playgroud)

反序列化代码:

List<Foo> foos = JsonConvert.DeserializeObject<List<Foo>>(json);
Run Code Online (Sandbox Code Playgroud)

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

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

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

Flo*_*eda 28

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

用法示例:

var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;

JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);
Run Code Online (Sandbox Code Playgroud)

更多信息在这里.

  • 他要求忽略特定键不处理缺失键,你的回答与问题无关 (33认同)
  • 有趣的是,我们中有多少人实际上正在寻找这个答案 - 即我们有一个不同的问题,但我们得到的答案是正确的。我几乎感觉超现实 (2认同)

Dha*_*run 10

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

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

}
Run Code Online (Sandbox Code Playgroud)

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


Mas*_*low 8

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

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

public class DynamicContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, 
        MemberSerialization memberSerialization)
    {
        Func<Type,bool> includeProperty = t => t.IsValueType || t.Namespace.StartsWith("System") && t.Namespace.StartsWith("System.Data")==false; 
        IList<JsonProperty> 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

所有.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();
Run Code Online (Sandbox Code Playgroud)