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

C# JSON.Net在反序列化期间忽略属性,c#,json,json.net,C#,Json,Json.net,我的课程设置如下: public class Foo { public string string1 { get; set; } public string string2 { get; set; } public string string3 { get; set; } } 我正在使用Json.Net反序列化以下Json响应: [ { “数字1”:1, “数字2”:123456789001234567890, “数字3”:3 }, { “数字1”:9, “数字2”:1

我的课程设置如下:

public class Foo
{
    public string string1 { get; set; }
    public string string2 { get; set; }
    public string string3 { get; set; }
}
我正在使用Json.Net反序列化以下Json响应:

[
{
“数字1”:1,
“数字2”:123456789001234567890,
“数字3”:3
},
{
“数字1”:9,
“数字2”:123456789001234567890,
“数字3”:8
}
]
反序列化代码:

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

List<Foo> foos = JsonConvert.DeserializeObject<List<Foo>>(json);
stringjson=@”[
{
“数字1”:1,
“编号2”:123456789001234567890,
“编号3”:3
},
{
“数字1”:9,
“编号2”:123456789001234567890,
“编号3”:8
}
]"
List foos=JsonConvert.DeserializeObject(json);
number2
中的值超过了
Int64
,但我并不真正关心检索该值。有没有办法将
number2
属性强制转换为字符串,或者在反序列化过程中完全忽略它

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


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

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

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

}
来自JSON的公共静态列表(字符串输入){ var json=JToken.Parse(输入); json[“key”].Remove(); var foo=JsonConvert.DeserializeObject(json.ToString()); }

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

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

用法示例:

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();
var jsonSerializerSettings=new jsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling=MissingMemberHandling.Ignore;
反序列化对象(jsonResponse、jsonSerializerSettings);

更多信息。

以下是Newtonsoft Json首选的忽略属性的方法,而无需根据

这一个用于忽略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;
    }
}
与类似,您可以使用:

对drzaus的回答补充如下: 您可以使用他建议的
DefaultContractResolver
。。仅在其
CreateProperty
中使用
property.Ignored=true
而不是
属性。应该序列化
,然后将
JsonSerializerSettings
传递给
反序列化对象
函数或
序列化对象
函数都很好

如果ResponseAttribute在模型或字符串参数中具有

public class ResponseAttribute : Attribute { }

public class ModelItem
{
    [Response]
    public Guid Id { get; set; }
}
代码


我遇到了类似的情况,但我的类包含了列表和字典,它们是填充的,不应该被JSON文件中的任何内容覆盖。对我来说,将数据加载到一个scratch对象中,然后只提取所需的项,这比当时我能找到的任何其他方法都要容易

所以对于这个例子,像这样的东西

public class Foo
{
    public string string1 { get; set; }
    public string string2 { get; set; }
    public string string3 { get; set; }
}
List<Foo> foos = new List<Foo>();

List<Foo> tmp= JsonConvert.DeserializeObject<List<Foo>>(json);

foreach(Foo item in tmp)
{
    foos.string1 = tmp.string1;
    foos.string3 = tmp.string3;
}
公共类Foo
{
公共字符串string1{get;set;}
公共字符串string2{get;set;}
公共字符串string3{get;set;}
}
List foos=新列表();
List tmp=JsonConvert.DeserializeObject(json);
foreach(tmp中的Foo项目)
{
foos.string1=tmp.string1;
foos.string3=tmp.string3;
}

这段代码对我来说很有魅力:

using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class PropertyRenameAndIgnoreSerializerContractResolver : DefaultContractResolver
{
    private readonly Dictionary<Type, HashSet<string>> _ignores;
    private readonly Dictionary<Type, Dictionary<string, string>> _renames;

    public PropertyRenameAndIgnoreSerializerContractResolver()
    {
        _ignores = new Dictionary<Type, HashSet<string>>();
        _renames = new Dictionary<Type, Dictionary<string, string>>();
    }

    public void IgnoreProperty(Type type, params string[] jsonPropertyNames)
    {
        if (!_ignores.ContainsKey(type))
            _ignores[type] = new HashSet<string>();

        foreach (var prop in jsonPropertyNames)
            _ignores[type].Add(prop);
    }

    public void RenameProperty(Type type, string propertyName, string newJsonPropertyName)
    {
        if (!_renames.ContainsKey(type))
            _renames[type] = new Dictionary<string, string>();

        _renames[type][propertyName] = newJsonPropertyName;
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        if (IsIgnored(property.DeclaringType, property.PropertyName))
        {
            property.ShouldSerialize = i => false;
            property.Ignored = true;
        }

        if (IsRenamed(property.DeclaringType, property.PropertyName, out var newJsonPropertyName))
            property.PropertyName = newJsonPropertyName;

        return property;
    }

    private bool IsIgnored(Type type, string jsonPropertyName)
    {
        if (!_ignores.ContainsKey(type))
            return false;

        return _ignores[type].Contains(jsonPropertyName);
    }

    private bool IsRenamed(Type type, string jsonPropertyName, out string newJsonPropertyName)
    {
        Dictionary<string, string> renames;

        if (!_renames.TryGetValue(type, out renames) || !renames.TryGetValue(jsonPropertyName, out newJsonPropertyName))
        {
            newJsonPropertyName = null;
            return false;
        }

        return true;
    }
}
使用系统反射;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Serialization;
公共类属性yrenameAndignoreserializerContractResolver:DefaultContractResolver
{
私人只读字典(u忽略);;
私有只读词典_重命名;
公共财产域名域名争议仲裁合同解析程序()
{
_忽略=新字典();
_重命名=新字典();
}
public void IgnoreProperty(类型类型,参数字符串[]jsonPropertyNames)
{
如果(!\u忽略.ContainsKey(类型))
_忽略[type]=新哈希集();
foreach(jsonPropertyNames中的var prop)
_忽略[type]。添加(道具);
}
公共void重命名属性(类型类型、字符串propertyName、字符串newJsonPropertyName)
{
如果(!\u重命名.ContainsKey(类型))
_重命名[类型]=新字典();
_重命名[type][propertyName]=newJsonPropertyName;
}
受保护的重写JsonProperty CreateProperty(MemberInfo成员、MemberSerialization MemberSerialization)
{
var property=base.CreateProperty(成员,成员序列化);
if(IsIgnored(property.DeclaringType、property.PropertyName))
{
property.ShouldSerialize=i=>false;
property.Ignored=true;
}
if(isRename(property.DeclaringType、property.PropertyName、out var newJsonPropertyName))
property.PropertyName=newJsonPropertyName;
归还财产;
}
private bool IsIgnored(类型,字符串jsonPropertyName)
{
如果(!\u忽略.ContainsKey(类型))
返回false;
返回_忽略[type]。包含(jsonPropertyName);
}
private bool isrename(类型类型,字符串jsonPropertyName,输出字符串newJsonPropertyName)
{
字典更名;
如果(!_重命名.TryGetValue(类型,输出重命名)| |!重命名.TryGetValue(jsonPropertyName,输出新jsonPropertyName))
{
newJsonPropertyName=null;
返回false;
}
返回true;
}
}
//忽略Foo示例中的number2

public class Foo
{
public string number1 { get; set; }
public string number2 { get; set; }
public string number3 { get; set; }
}
    string Foojson = @"[
    {
        ""number1"": 1,
        ""number2"": 12345678901234567890,
        ""number3"": 3
    },
    {
        ""number1"": 9,
        ""number2"": 12345678901234567890,
        ""number3"": 8
    }
]";
var jsonResolverFoo = new PropertyRenameAndIgnoreSerializerContractResolver();
jsonResolverFoo.IgnoreProperty(typeof(Foo), "number2");
var serializerSettingsFoo = new JsonSerializerSettings();
serializerSettingsFoo.ContractResolver = jsonResolverFoo;
var deserializedJsonFoo = JsonConvert.DeserializeObject<List<Foo>>(Foojson, serializerSettingsFoo);
公共类Foo
{
公共字符串编号1{get;set;}
公共字符串编号2{get;set;}
公共字符串编号3{get;set;}
}
字符串Foojson=@”[
{
“数字1”:1,
“编号2”:123456789001234567890,
“编号3”:3
},
{
“数字1”:9,
“数字2”:123456789
return new JsonResult(model, new CustomJsonSerializer("Id","Test","Test2"));
public class Foo
{
    public string string1 { get; set; }
    public string string2 { get; set; }
    public string string3 { get; set; }
}
List<Foo> foos = new List<Foo>();

List<Foo> tmp= JsonConvert.DeserializeObject<List<Foo>>(json);

foreach(Foo item in tmp)
{
    foos.string1 = tmp.string1;
    foos.string3 = tmp.string3;
}
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class PropertyRenameAndIgnoreSerializerContractResolver : DefaultContractResolver
{
    private readonly Dictionary<Type, HashSet<string>> _ignores;
    private readonly Dictionary<Type, Dictionary<string, string>> _renames;

    public PropertyRenameAndIgnoreSerializerContractResolver()
    {
        _ignores = new Dictionary<Type, HashSet<string>>();
        _renames = new Dictionary<Type, Dictionary<string, string>>();
    }

    public void IgnoreProperty(Type type, params string[] jsonPropertyNames)
    {
        if (!_ignores.ContainsKey(type))
            _ignores[type] = new HashSet<string>();

        foreach (var prop in jsonPropertyNames)
            _ignores[type].Add(prop);
    }

    public void RenameProperty(Type type, string propertyName, string newJsonPropertyName)
    {
        if (!_renames.ContainsKey(type))
            _renames[type] = new Dictionary<string, string>();

        _renames[type][propertyName] = newJsonPropertyName;
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        if (IsIgnored(property.DeclaringType, property.PropertyName))
        {
            property.ShouldSerialize = i => false;
            property.Ignored = true;
        }

        if (IsRenamed(property.DeclaringType, property.PropertyName, out var newJsonPropertyName))
            property.PropertyName = newJsonPropertyName;

        return property;
    }

    private bool IsIgnored(Type type, string jsonPropertyName)
    {
        if (!_ignores.ContainsKey(type))
            return false;

        return _ignores[type].Contains(jsonPropertyName);
    }

    private bool IsRenamed(Type type, string jsonPropertyName, out string newJsonPropertyName)
    {
        Dictionary<string, string> renames;

        if (!_renames.TryGetValue(type, out renames) || !renames.TryGetValue(jsonPropertyName, out newJsonPropertyName))
        {
            newJsonPropertyName = null;
            return false;
        }

        return true;
    }
}
public class Foo
{
public string number1 { get; set; }
public string number2 { get; set; }
public string number3 { get; set; }
}
    string Foojson = @"[
    {
        ""number1"": 1,
        ""number2"": 12345678901234567890,
        ""number3"": 3
    },
    {
        ""number1"": 9,
        ""number2"": 12345678901234567890,
        ""number3"": 8
    }
]";
var jsonResolverFoo = new PropertyRenameAndIgnoreSerializerContractResolver();
jsonResolverFoo.IgnoreProperty(typeof(Foo), "number2");
var serializerSettingsFoo = new JsonSerializerSettings();
serializerSettingsFoo.ContractResolver = jsonResolverFoo;
var deserializedJsonFoo = JsonConvert.DeserializeObject<List<Foo>>(Foojson, serializerSettingsFoo);