[c#] Eine Eigenschaft deserialisieren, aber nicht mit json.net serialisieren



Answers

Ich mag es, mit Attributen zu bleiben, hier ist die Methode, die ich benutze, wenn ich eine Eigenschaft deserialisieren, aber nicht serialisieren muss oder umgekehrt.

SCHRITT 1 - Erstellen Sie das benutzerdefinierte Attribut

public class JsonIgnoreSerializationAttribute : Attribute { }

SCHRITT 2 - Erstellen Sie einen benutzerdefinierten Contract Reslover

class JsonPropertiesResolver : DefaultContractResolver
{
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        //Return properties that do NOT have the JsonIgnoreSerializationAttribute
        return objectType.GetProperties()
                         .Where(pi => !Attribute.IsDefined(pi, typeof(JsonIgnoreSerializationAttribute)))
                         .ToList<MemberInfo>();
    }
}

SCHRITT 3 - Attribut hinzufügen, wenn Serialisierung nicht benötigt wird, aber Deserialisierung ist

    [JsonIgnoreSerialization]
    public string Prop1 { get; set; } //Will be skipped when serialized

    [JsonIgnoreSerialization]
    public string Prop2 { get; set; } //Also will be skipped when serialized

    public string Prop3 { get; set; } //Will not be skipped when serialized

SCHRITT 4 - Benutze es

var sweet = JsonConvert.SerializeObject(myObj, new JsonSerializerSettings { ContractResolver = new JsonPropertiesResolver() });

Hoffe das hilft! Es ist auch erwähnenswert, dass dies auch die Eigenschaften ignoriert, wenn die Deserialisierung stattfindet. Wenn ich das Deserialisieren verwende, benutze ich einfach den Konverter auf die herkömmliche Weise.

JsonConvert.DeserializeObject<MyType>(myString);
Question

Wir haben einige Konfigurationsdateien, die durch das Serialisieren von C # -Objekten mit Json.net generiert wurden.

Wir möchten eine Eigenschaft der serialisierten Klasse von einer einfachen enum-Eigenschaft in eine Klasseneigenschaft migrieren.

Ein einfacher Weg, dies zu tun, wäre, die alte enum-Eigenschaft der Klasse zu belassen und dafür zu sorgen, dass Json.net diese Eigenschaft liest, wenn wir die Konfiguration laden, aber nicht, um sie beim nächsten Serialisieren des Objekts erneut zu speichern. Wir werden uns darum kümmern, die neue Klasse aus dem alten Enum separat zu generieren.

Gibt es eine einfache Möglichkeit, eine Eigenschaft eines C # -Objekts zu markieren (zB mit Attributen), so dass Json.net es NUR bei der Serialisierung ignoriert, aber beim Deserialisieren darauf achtet?




Nachdem ich eine lange Zeit damit verbracht habe zu suchen, wie man eine Klasseneigenschaft als De-Serializable und NICHT als Serializable kennzeichnet, habe ich festgestellt, dass es so etwas überhaupt nicht zu tun gibt; Also kam ich auf eine Lösung, die zwei verschiedene Bibliotheken oder Serialisierungstechniken (System.Runtime.Serialization.Json & Newtonsoft.Json) kombiniert und es funktionierte für mich wie folgt:

  • Kennzeichnen Sie alle Ihre Klassen und Unterklassen als "DataContract".
  • Kennzeichnen Sie alle Eigenschaften Ihrer Klasse und Unterklassen als "DataMember".
  • Kennzeichnen Sie alle Eigenschaften Ihrer Klasse und Unterklassen als "JsonProperty" mit Ausnahme derer, die nicht serialisiert werden sollen.
  • Markieren Sie nun die Eigenschaften, die NICHT als "JsonIgnore" serialisiert werden sollen.
  • Serialisieren Sie dann mithilfe von "Newtonsoft.Json.JsonConvert.SerializeObject" und De-Serialize mithilfe von "System.Runtime.Serialization.Json.DataContractJsonSerializer".

    using System;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    using System.Runtime.Serialization;
    using System.IO;
    using System.Runtime.Serialization.Json;
    using System.Text;
    
    namespace LUM_Win.model
    {
        [DataContract]
        public class User
        {
            public User() { }
            public User(String JSONObject)
            {
                MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(JSONObject));
                DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(User));
    
                User user = (User)dataContractJsonSerializer.ReadObject(stream);
                this.ID = user.ID;
                this.Country = user.Country;
                this.FirstName = user.FirstName;
                this.LastName = user.LastName;
                this.Nickname = user.Nickname;
                this.PhoneNumber = user.PhoneNumber;
                this.DisplayPicture = user.DisplayPicture;
                this.IsRegistred = user.IsRegistred;
                this.IsConfirmed = user.IsConfirmed;
                this.VerificationCode = user.VerificationCode;
                this.Meetings = user.Meetings;
            }
    
            [DataMember(Name = "_id")]
            [JsonProperty(PropertyName = "_id")]
            public String ID { get; set; }
    
            [DataMember(Name = "country")]
            [JsonProperty(PropertyName = "country")]
            public String Country { get; set; }
    
            [DataMember(Name = "firstname")]
            [JsonProperty(PropertyName = "firstname")]
            public String FirstName { get; set; }
    
            [DataMember(Name = "lastname")]
            [JsonProperty(PropertyName = "lastname")]
            public String LastName { get; set; }
    
            [DataMember(Name = "nickname")]
            [JsonProperty(PropertyName = "nickname")]
            public String Nickname { get; set; }
    
            [DataMember(Name = "number")]
            [JsonProperty(PropertyName = "number")]
            public String PhoneNumber { get; set; }
    
            [DataMember(Name = "thumbnail")]
            [JsonProperty(PropertyName = "thumbnail")]
            public String DisplayPicture { get; set; }
    
            [DataMember(Name = "registered")]
            [JsonProperty(PropertyName = "registered")]
            public bool IsRegistred { get; set; }
    
            [DataMember(Name = "confirmed")]
            [JsonProperty(PropertyName = "confirmed")]
            public bool IsConfirmed { get; set; }
    
            [JsonIgnore]
            [DataMember(Name = "verification_code")]
            public String VerificationCode { get; set; }
    
            [JsonIgnore]
            [DataMember(Name = "meeting_ids")]
            public List<Meeting> Meetings { get; set; }
    
            public String toJSONString()
            {
                return JsonConvert.SerializeObject(this, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
            }
        }
    }
    

Ich hoffe, das hilft ...




In Bezug auf die Lösung von @ ThoHo ist die Verwendung des Setter eigentlich alles, was benötigt wird, ohne zusätzliche Tags.

Für mich hatte ich vorher eine einzige Referenz-ID, die ich laden und der neuen Sammlung von Referenz-IDs hinzufügen wollte. Indem Sie die Definition der Referenz-ID so ändern, dass sie nur eine Setter-Methode enthält, die den Wert zur neuen Sammlung hinzugefügt hat. Json kann den Wert nicht zurückschreiben, wenn die Eigenschaft kein get hat; Methode.

// Old property that I want to read from Json, but never write again. No getter.
public Guid RefId { set { RefIds.Add(value); } }

// New property that will be in use from now on. Both setter and getter.
public ICollection<Guid> RefIds { get; set; }

Diese Klasse ist nun abwärtskompatibel zur vorherigen Version und speichert nur die RefIds für die neuen Versionen.




Links



Tags

c# c#   json.net