it-swarm.com.de

JSON.Net Ignoriere Eigenschaft während der Deserialisierung

Ich habe eine Klasse wie folgt eingerichtet:

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

Ich verwende Json.Net, um die folgende Json-Antwort zu deserialisieren:

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

Deserialisierungscode: 

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

Die zweite Zahl überschreitet einen int-64-Wert, aber es interessiert mich nicht wirklich, diesen Wert abzurufen. Gibt es eine Möglichkeit, die 'number2'-Eigenschaft in eine Zeichenfolge umzuwandeln oder sie während der Deserialisierung vollständig zu ignorieren?

Ich habe versucht, der Eigenschaft 'string2' das Attribut '[JsonConverter (type) (string))] "hinzuzufügen, erhalte aber den Fehler:' Fehler beim Erstellen von System.String '. Ich habe auch versucht, typeof (dezimal) einzustellen.

Ich habe auch versucht, [JsonIgnore] zu verwenden, aber das funktioniert nicht.

25
FEXTWOLF

Sie können die MissingMemberHandling-Eigenschaft des JsonSerializerSettings-Objekts verwenden.

Verwendungsbeispiel:

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

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

Mehr Infos hier .

26
Florin D. Preda

Dies ist eine lahme Problemumgehung, aber Sie könnten eine Methode zum manuellen Laden des Json erstellen. Wenn zu viele Daten ohne einen automatischen Deserializer geladen werden sollen, entfernen Sie einfach die Knoten, die Sie nicht möchten. Dies ist jedoch viel langsamer.

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

}

Dies ist ein interessantes Problem. Ich frage mich, ob jemand eine bessere Lösung hat.

9
Dharun

Die Newtonsoft Json hat es vorgezogen, eine Eigenschaft zu ignorieren, ohne die Klasse basierend auf http://james.newtonking.com/json/help/index.html?topic=html/ReducingSerializedJSONSize.htm ändern zu müssen.

Dieser wird verwendet, um Lazy-Referenzeigenschaften von EF oder Linq2Sql zu ignorieren

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

Bei allen .Dump()-Aufrufen handelt es sich lediglich um Linqpad-Debugging-Helfer, nicht um Methodenaufrufe.

verwendungsbeispiel:

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();
7
Maslow

Ähnlich wie @ Maslows Lösung können Sie einen anderen universellen "ignorer" verwenden:

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

Hinzufügen zu drzaus answer: Sie können die DefaultContractResolver verwenden, die er vorgeschlagen hat. Nur in CreateProperty verwenden Sie property.Ignored = true; anstelle von property.ShouldSerialize. Dann ist es gut, wenn Sie die JsonSerializerSettings an die DeserializeObject-Funktion oder die SerializeObject-Funktion übergeben.

0
Ohad Bitton