web-dev-qa-db-ja.com

デシリアライズ中のJSON.Net Ignoreプロパティ

次のように設定されたクラスがあります。

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<Foo> foos = JsonConvert.DeserializeObject<List<Foo>>(json);

2番目の数値はint-64を超えていますが、その値を取得することはあまり気にしません。 「number2」プロパティを文字列にキャストする方法、または逆シリアル化中にそれを完全に無視する方法はありますか?

'[JsonConverter(typeof(string))]'属性をstring2プロパティに追加しようとしましたが、エラー: 'Error creating System.String'を受け取りました。 typeof(decimal)の設定も試みました。

[JsonIgnore]の使用も試みましたが、うまくいきません。

29
FEXTWOLF

MissingMemberHandlingオブジェクトのJsonSerializerSettingsプロパティを使用できます。

使用例:

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

JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);

詳細 こちら

30
Florin D. Preda

これは不十分な回避策ですが、jsonを手動でロードする方法を作成できます。自動デシリアライザなしでロードするにはデータが多すぎる場合は、不要なノードを削除してください。しかし、これはかなり遅いです。

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

}

これは興味深い問題です。誰かがそれに対するより良い解決策を持っているのだろうか。

11
Dharun

http://james.newtonking.com/json/help/index.html?topic=html/ReducingSerializedJSONSize.htm に基づいてクラスを変更することなく、プロパティを無視する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;
    }
}
_

すべての.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();
_
8
Maslow

@ Maslowのソリューション と同様に、 別の汎用「イグノラー」 を使用できます。

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 };
3
drzaus

Drzausの答えに追加:彼が提案したDefaultContractResolverを使用することができます.. CreateProperty use property.Ignored = true; の代わりに property.ShouldSerialize、その後JsonSerializerSettingsDeserializeObject関数またはSerializeObject関数に渡す場合に有効です。

0
Ohad Bitton