C# 如何从 Json 序列化中排除属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10169648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 12:43:03  来源:igfitidea点击:

How to exclude property from Json Serialization

c#json

提问by Elad Benda

I have a DTO class which I Serialize

我有一个我序列化的 DTO 类

Json.Serialize(MyClass)

How can I exclude a publicproperty of it?

我怎样才能排除它的公共财产?

(It has to be public, as I use it in my code somewhere else)

(它必须是公开的,因为我在其他地方的代码中使用它)

采纳答案by Pavel Krymets

If you are using System.Web.Script.Serializationin the .NET frameworkyou can put a ScriptIgnoreattribute on the members that shouldn't be serialized. See the example taken from here:

如果您System.Web.Script.Serialization在 .NET 框架中使用,您可以ScriptIgnore在不应序列化的成员上放置一个属性。请参阅从此处获取的示例:

Consider the following (simplified) case:

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

In this case, only the Id and the Name properties will be serialized, thus the resulting JSON object would look like this:

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

考虑以下(简化的)情况:

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

在这种情况下,只有 Id 和 Name 属性将被序列化,因此生成的 JSON 对象将如下所示:

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

PS.Don't forget to add a reference to "System.Web.Extensions" for this to work

附注。不要忘记添加对“ System.Web.Extensions”的引用以使其工作

回答by Arion

You can use [ScriptIgnore]:

您可以使用[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); }
    }
}

Reference here

参考这里

In this case the Id and then name will only be serialized

在这种情况下,Id 和 name 只会被序列化

回答by JC Raja

If you are using Json.Netattribute [JsonIgnore]will simply ignore the field/property while serializing or deserialising.

如果您使用 Json.Net属性[JsonIgnore]将在序列化或反序列化时简单地忽略字段/属性。

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

Or you can use DataContract and DataMember attribute to selectively serialize/deserialize properties/fields.

或者您可以使用 DataContract 和 DataMember 属性来选择性地序列化/反序列化属性/字段。

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

Refer http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-sizefor more details

有关更多详细信息,请参阅http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size

回答by Thulani Chivandikwa

If you are not so keen on having to decorate code with Attributes as I am, esp when you cant tell at compile time what will happen here is my solution.

如果您不像我那样热衷于使用属性来装饰代码,尤其是当您在编译时无法判断这里会发生什么时,这是我的解决方案。

Using the Javascript Serializer

使用 Javascript 序列化程序

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

回答by Yes Barry

You can also use the [NonSerialized]attribute

您还可以使用该[NonSerialized]属性

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

From the MS docs:

从 MS 文档

Indicates that a field of a serializable class should not be serialized. This class cannot be inherited.

指示不应序列化可序列化类的字段。这个类不能被继承。



If you're using Unity for example (this isn't only for Unity) then this works with UnityEngine.JsonUtility

例如,如果您使用 Unity (这不仅适用于 Unity),那么这适用于UnityEngine.JsonUtility

using UnityEngine;

MySerializableStruct mss = new MySerializableStruct 
{ 
    hiddenField = "foo", 
    normalField = "bar" 
};
Debug.Log(JsonUtility.ToJson(mss)); // result: {"normalField":"bar"}

回答by Travis

If you are using System.Text.Jsonthen you can use [JsonIgnore].
FQ: System.Text.Json.Serialization.JsonIgnoreAttribute

如果您正在使用,System.Text.Json那么您可以使用[JsonIgnore].
问:System.Text.Json.Serialization.JsonIgnoreAttribute

Official Microsoft Docs: JsonIgnoreAttribute

官方 Microsoft Docs:JsonIgnoreAttribute

As stated here:

如前所述这里

The library is built-in as part of the .NET Core 3.0 shared framework.
For other target frameworks, install the System.Text.Json NuGet package. The package supports:

  • .NET Standard 2.0 and later versions
  • .NET Framework 4.6.1 and later versions
  • .NET Core 2.0, 2.1, and 2.2

该库作为 .NET Core 3.0 共享框架的一部分内置。
对于其他目标框架,请安装 System.Text.Json NuGet 包。该软件包支持:

  • .NET Standard 2.0 及更高版本
  • .NET Framework 4.6.1 及更高版本
  • .NET 核心 2.0、2.1 和 2.2

回答by Alex

Sorry I decided to write another answer since none of the other answers are copy-pasteable enough.

对不起,我决定写另一个答案,因为其他答案都不够复制粘贴。

If you don't want to decorate properties with some attributes, or if you have no access to the class, or if you want to decide what to serialize during runtime, etc. etc. here's how you do it in Newtonsoft.Json

如果您不想使用某些属性来装饰属性,或者您无法访问该类,或者您想决定在运行时序列化什么等等,那么您可以在 Newtonsoft.Json 中执行此操作

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

Usage

用法

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

I've published the code here in case anyone wants to add anything

我已经在这里发布了代码以防有人想添加任何东西

https://github.com/jitbit/JsonIgnoreProps

https://github.com/jitbit/JsonIgnoreProps

IMPORTANT UPDATE:make sure you cache the ContractResolverobject if you decide to use this answer, otherwise performance may suffer.

重要更新:ContractResolver如果您决定使用此答案,请确保缓存对象,否则性能可能会受到影响。