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
JsonPropertyAttributeorSystem.Runtime.Serialization.DataMemberAttributeare 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)
CodePudding user response:
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);
