Mülkiyet Json Serileştirmesi'nden hariç tutma


235

Serialize ettiğim bir DTO sınıfım var

Json.Serialize(MyClass)

Bir kamu mülkünü nasıl hariç tutabilirim ?

(Kodumda başka bir yerde kullandığım için herkese açık olmalı)


4
Hangi serileştirme çerçevesini kullanıyorsunuz?
Pavel Gatilov

37
IgnoreDataMember ScriptIgnore JsonIgnoreKullandığınız serileştiriciye bağlı olarak
LB

3
Ayrıca, yalnızca alanlar (özellikler için değil) için geçerli olan, ancak Aksi takdirde JsonIgnore ile aynı etkiye sahip olan [Seri Olmayan] özniteliğidir.
Triynko

Trynko'nun yorumu çok faydalıdır .... IgnoreDataMember'i bir alanda kullanırsanız hata olmaz, ancak uygulanmayacaktır.
Tillito

Yanıtlar:


147

System.Web.Script.Serialization.NET çerçevesinde kullanıyorsanız ,ScriptIgnore serileştirilmemesi gereken üyelere bir öznitelik koyabilirsiniz . Buradan alınan örneğe bakın :

Aşağıdaki (basitleştirilmiş) durumu düşünün:

public class User {
    public int Id { get; set; }
    public string Name { get; set; }
    [ScriptIgnore]
    public bool IsComplete
    {
        get { return Id > 0 && !string.IsNullOrEmpty(Name); }
    } 
} 

Bu durumda, yalnızca Id ve Name özellikleri serileştirilir, böylece elde edilen JSON nesnesi şöyle görünür:

{ Id: 3, Name: 'Test User' }

PS. Bunun System.Web.Extensionsçalışması için " " öğesine bir referans eklemeyi unutmayın


10
Bulduğum ScriptIgnoreiçinde System.Web.Script.Serializationad.
Sorangwala Abbasali

354

Json.Net özniteliğini kullanıyorsanız[JsonIgnore] , serileştirirken veya serileştirmeyi kaldırırken alanı / özelliği yoksayar.

public class Car
{
  // included in JSON
  public string Model { get; set; }
  public DateTime Year { get; set; }
  public List<string> Features { get; set; }

  // ignored
  [JsonIgnore]
  public DateTime LastModified { get; set; }
}

Veya özellikleri / alanları seçici olarak serileştirmek / serisini kaldırmak için DataContract ve DataMember özniteliğini kullanabilirsiniz.

[DataContract]
public class Computer
{
  // included in JSON
  [DataMember]
  public string Name { get; set; }
  [DataMember]
  public decimal SalePrice { get; set; }

  // ignored
  public string Manufacture { get; set; }
  public int StockCount { get; set; }
  public decimal WholeSalePrice { get; set; }
  public DateTime NextShipmentDate { get; set; }
}

Daha fazla bilgi için http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size adresine bakın.


37
Ben OP olsaydım, bu cevabı seçilen [ScriptIgnore] çözümü yerine tercih ederim. Öncelikle bir Json çözümünün uyumu nedeniyle bir Json sorunu. Kullandığınız kitaplık bir çözüm sağlarken neden System.Web.Extensions'ı dahil etmelisiniz? Mutlak en iyi IMHO [IgnoreDataMember] özniteliğidir, çünkü Json'u takas etmek isterseniz System.Runtime.Serialization her serileştiriciyle uyumlu olmalıdır.
Steve H.

IgnoreDataMembervarsayılan JsonResultserileştiriciyle çalışmaz .
hendryanw

1
NewtonSoft bana tam anlamıyla yardımcı oldu. Sadece arka uç için olan modellerimden dahil edilen dağınık özellikler olmadan json'umun temiz görünmesini sağladı.
Sorangwala Abbasali

1
@JC Raja Tuzdan arındırma sırasında sadece bu özellik null olduğunda mülkiyeti nasıl yok sayabilirim
user123456

1
[NewtonSoft.Json] Yalnızca serileştirmeyi yok saymak istiyorum. Peki bunun için bir çözüm var mı?
Trống Quốc Khánh

31

Şunları kullanabilirsiniz [ScriptIgnore]:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    [ScriptIgnore]
    public bool IsComplete
    {
        get { return Id > 0 && !string.IsNullOrEmpty(Name); }
    }
}

Burada referans

Bu durumda Kimlik ve ardından ad yalnızca serileştirilir


1
Cevabınızdaki URL bozuk. Is [ScriptIgnore]Denetleyiciniz tabanını MVC denetleyicisi kullanıyorsa mülkiyet ne kullanılmalıdır return Json(...?
Don Cheadle

2
Eski bir yorum olduğunu biliyorum, ama evet, [ScriptIgnore]MVC Denetleyici kullanın . Ancak, SignalR kullanıyorsanız , o zaman da kullanmalısınız [JsonIgnore].
Sam

22

Üzgünüm, diğer cevapların hiçbiri yeterince kopyalanamayacağı için başka bir cevap yazmaya karar verdim.

Bazı özniteliklerle özellikleri süslemek istemiyorsanız veya sınıfa erişiminiz yoksa veya çalışma zamanı vb. Sırasında neyin seri hale getirileceğini belirlemek istiyorsanız vs.

//short helper class to ignore some properties from serialization
public class IgnorePropertiesResolver : DefaultContractResolver
{
    private IEnumerable<string> _propsToIgnore;
    public IgnorePropertiesResolver(IEnumerable<string> propNamesToIgnore)
    {
        _propsToIgnore = propNamesToIgnore;
    }
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        property.ShouldSerialize = (x) => { return !_propsToIgnore.Contains(property.PropertyName); };
        return property;
    }
}

kullanım

JsonConvert.SerializeObject(YourObject, new JsonSerializerSettings()
    { ContractResolver = new IgnorePropertiesResolver(new[] { "Prop1", "Prop2" }) };);

Herkes bir şey eklemek istiyorsa kodu burada yayınladım

https://github.com/jitbit/JsonIgnoreProps

ÖNEMLİ GÜNCELLEME:ContractResolver Bu yanıtı kullanmaya karar verirseniz nesneyi önbelleğe aldığınızdan emin olun , aksi takdirde performans düşebilir.


15

Benim gibi Nitelikler ile kod süslemek zorunda değilseniz, esp derlemek zaman burada ne olacağını söyleyemem benim çözümdür.

Javascript Serializer'ı Kullanma

    public static class JsonSerializerExtensions
    {
        public static string ToJsonString(this object target,bool ignoreNulls = true)
        {
            var javaScriptSerializer = new JavaScriptSerializer();
            if(ignoreNulls)
            {
                javaScriptSerializer.RegisterConverters(new[] { new PropertyExclusionConverter(target.GetType(), true) });
            }
            return javaScriptSerializer.Serialize(target);
        }

        public static string ToJsonString(this object target, Dictionary<Type, List<string>> ignore, bool ignoreNulls = true)
        {
            var javaScriptSerializer = new JavaScriptSerializer();
            foreach (var key in ignore.Keys)
            {
                javaScriptSerializer.RegisterConverters(new[] { new PropertyExclusionConverter(key, ignore[key], ignoreNulls) });
            }
            return javaScriptSerializer.Serialize(target);
        }
    }


public class PropertyExclusionConverter : JavaScriptConverter
    {
        private readonly List<string> propertiesToIgnore;
        private readonly Type type;
        private readonly bool ignoreNulls;

        public PropertyExclusionConverter(Type type, List<string> propertiesToIgnore, bool ignoreNulls)
        {
            this.ignoreNulls = ignoreNulls;
            this.type = type;
            this.propertiesToIgnore = propertiesToIgnore ?? new List<string>();
        }

        public PropertyExclusionConverter(Type type, bool ignoreNulls)
            : this(type, null, ignoreNulls){}

        public override IEnumerable<Type> SupportedTypes
        {
            get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { this.type })); }
        }

        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            var result = new Dictionary<string, object>();
            if (obj == null)
            {
                return result;
            }
            var properties = obj.GetType().GetProperties();
            foreach (var propertyInfo in properties)
            {
                if (!this.propertiesToIgnore.Contains(propertyInfo.Name))
                {
                    if(this.ignoreNulls && propertyInfo.GetValue(obj, null) == null)
                    {
                         continue;
                    }
                    result.Add(propertyInfo.Name, propertyInfo.GetValue(obj, null));
                }
            }
            return result;
        }

        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException(); //Converter is currently only used for ignoring properties on serialization
        }
    }

1
Mantık ve küçük bir değişiklik PropertyExclusionConverterbir a dönüştürülebilir PropertyInclusionConverter.
Zarepheth

Bu sadece harika
SaiKiran Mandhala

Bununla ilgili potansiyel bir sorun, bir nesne serileştirildiğinde ad eşleştirme ve hariç tutma işini tekrar tekrar yapması gerektiğidir. Ancak, bir kez derlendiğinde, bir türün özellikleri değişmez - bu tür, her bir tür için, dahil edilmesi gereken adları önceden hesaplamalı ve sadece her satırdaki listeyi yeniden kullanmalısınız. Çok büyük bir JSON serileştirme işi için önbellekleme, performansta gözle görülür bir fark yaratabilir.
ErikE

9

Eğer kullanıyorsanız System.Text.Jsono zaman kullanabilirsiniz [JsonIgnore].
FQ:System.Text.Json.Serialization.JsonIgnoreAttribute

Resmi Microsoft Belgeleri: JsonIgnoreAttribute

Belirtildiği gibi burada :

Kitaplık, .NET Core 3.0 paylaşılan çerçevesinin bir parçası olarak yerleşiktir.
Diğer hedef çerçeveler için System.Text.Json NuGet paketini yükleyin. Paket şunları destekler:

  • .NET Standard 2.0 ve sonraki sürümler
  • .NET Framework 4.6.1 ve sonraki sürümleri
  • .NET Core 2.0, 2.1 ve 2.2

0

Ayrıca kullanabilirsiniz [NonSerialized]niteliğini

[Serializable]
public struct MySerializableStruct
{
    [NonSerialized]
    public string hiddenField;
    public string normalField;
}

MS belgelerinden :

Serileştirilebilir sınıftaki bir alanın serileştirilmemesi gerektiğini belirtir. Bu sınıf devralınamaz.


Örneğin Unity kullanıyorsanız ( bu sadece Unity için değil )UnityEngine.JsonUtility

using UnityEngine;

MySerializableStruct mss = new MySerializableStruct 
{ 
    hiddenField = "foo", 
    normalField = "bar" 
};
Debug.Log(JsonUtility.ToJson(mss)); // result: {"normalField":"bar"}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.