次のように設定されたクラスがあります。
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]の使用も試みましたが、うまくいきません。
MissingMemberHandling
オブジェクトのJsonSerializerSettings
プロパティを使用できます。
使用例:
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);
詳細 こちら 。
これは不十分な回避策ですが、jsonを手動でロードする方法を作成できます。自動デシリアライザなしでロードするにはデータが多すぎる場合は、不要なノードを削除してください。しかし、これはかなり遅いです。
public static List<Foo> FromJson(string input) {
var json = JToken.Parse(input);
json["key"].Remove();
var foo = JsonConvert.DeserializeObject<List<Foo>>(json.ToString());
}
これは興味深い問題です。誰かがそれに対するより良い解決策を持っているのだろうか。
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();
_
@ 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 };
Drzausの答えに追加:彼が提案したDefaultContractResolver
を使用することができます.. CreateProperty
use property.Ignored = true;
の代わりに property.ShouldSerialize
、その後JsonSerializerSettings
をDeserializeObject
関数またはSerializeObject
関数に渡す場合に有効です。