[c#] How to exclude property from Json Serialization

I have a DTO class which I Serialize

Json.Serialize(MyClass)

How can I exclude a public property of it?

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

This question is related to c# json

The answer is


If you are using System.Web.Script.Serialization in the .NET framework you can put a ScriptIgnore attribute on the members that shouldn't be serialized. See the example taken from here:

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

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


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

Official 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

You can use [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


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

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

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

//short helper class to ignore some properties from serialization
public class IgnorePropertiesResolver : DefaultContractResolver
{
    private readonly HashSet<string> ignoreProps;
    public IgnorePropertiesResolver(IEnumerable<string> propNamesToIgnore)
    {
        this.ignoreProps = new HashSet<string>(propNamesToIgnore);
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        if (this.ignoreProps.Contains(property.PropertyName))
        {
            property.ShouldSerialize = _ => false;
        }
        return property;
    }
}

Usage

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

Note: make sure you cache the ContractResolver object if you decide to use this answer, otherwise performance may suffer.

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

https://github.com/jitbit/JsonIgnoreProps


You can also use the [NonSerialized] attribute

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

From the MS docs:

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

using UnityEngine;

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