Crossoni
Crossoni

Reputation: 393

Json.Net ignore serialized private fields in Unity

I would like to ignore serialized private fields from json serialization, but it seems that [JsonIgnore] works only with public fields, it does not work with [SerializeField] private fields. Is there any other way to ignore those fields?

This is an example class:

using UnityEngine;
using Newtonsoft.Json;

[JsonObject(MemberSerialization.OptIn)]
public class ExampleObject : MonoBehaviour {
    [JsonProperty]
    private string property = "Property";

    [JsonIgnore]
    [SerializeField]
    private string ignored = "Ignored";
}

Output

{"property":"Property","ignored":"Ignored"}

It still serializes the ignored field to json, even though I am using [JsonObject(MemberSerialization.OptIn)] on the class and [JsonIgnore] on the private field.

MemberSerialization.OptIn says that

"Only members marked with JsonPropertyAttribute or System.Runtime.Serialization.DataMemberAttribute are serialized"

, but it also seems to include SerializeField attributes.

Edit: I am using JilleJr Newtonsoft.Json-for-Unity (github link) with JilleJr Newtonsoft.Json-for-Unity.Converters(github link)

Upvotes: 2

Views: 3035

Answers (2)

Ji Nguyen
Ji Nguyen

Reputation: 1

Just add "[SerializeField]"

[SerializeField]
private string userName;
[SerializeField]
private string password;

Upvotes: 0

dbc
dbc

Reputation: 116981

The problem is that the port of Json.NET that you are using, JilleJr Newtonsoft.Json-for-Unity.Converters, includes a custom contract resolver UnityTypeContractResolver that includes members marked with [SerializeField] even when also marked with [JsonIgnore]. From the source:

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
   JsonProperty jsonProperty = base.CreateProperty(member, memberSerialization);

   // A check for member.GetCustomAttribute<JsonIgnoreAttribute>() is missing in the following line:
   if (member.GetCustomAttribute<SerializeField>() != null) 
   {
       jsonProperty.Ignored = false;
       jsonProperty.Writable = CanWriteMemberWithSerializeField(member);
       jsonProperty.Readable = CanReadMemberWithSerializeField(member);
       jsonProperty.HasMemberAttribute = true;
   }

   return jsonProperty;
}

If you don't want this, you will need to subclass this contract resolver and correct the behavior:

public class FixedUnityTypeContractResolver : Newtonsoft.Json.UnityConverters.UnityTypeContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
       JsonProperty jsonProperty = base.CreateProperty(member, memberSerialization);

       if (!jsonProperty.Ignored && member.GetCustomAttribute<Newtonsoft.Json.JsonIgnoreAttribute>() != null) 
           jsonProperty.Ignored = true;

       return jsonProperty;
    }
}

And then serialize as follows:

// Cache and reuse the contract resolver throughout your project to improve performance.
static Newtonsoft.Json.Serialization.IContractResolver _resolver = new FixedUnityTypeContractResolver ();

var settings = new JsonSerializerSettings 
{
    ContractResolver = _resolver,
};
JsonConvert.SerializeObject(this, settings);

Upvotes: 3

Related Questions