Json.Net 忽略 Unity 中的序列化私有字段
Json.Net ignore serialized private fields in Unity
我想忽略 json 序列化中的序列化私有字段,但似乎 [JsonIgnore]
仅适用于 public
字段,不适用于 [SerializeField]
private
个字段。还有其他方法可以忽略这些字段吗?
这是一个例子class:
using UnityEngine;
using Newtonsoft.Json;
[JsonObject(MemberSerialization.OptIn)]
public class ExampleObject : MonoBehaviour {
[JsonProperty]
private string property = "Property";
[JsonIgnore]
[SerializeField]
private string ignored = "Ignored";
}
输出
{"property":"Property","ignored":"Ignored"}
它仍然将 ignored
字段序列化为 json,即使我在 class 上使用 [JsonObject(MemberSerialization.OptIn)]
并且在 [=16 上使用 [JsonIgnore]
=] 字段.
MemberSerialization.OptIn
说
"Only members marked with JsonPropertyAttribute
or System.Runtime.Serialization.DataMemberAttribute
are serialized"
,但它似乎还包括 SerializeField
属性。
编辑:我正在使用 JilleJr Newtonsoft.Json-for-Unity
(github link) with JilleJr Newtonsoft.Json-for-Unity.Converters
(github link)
问题是您正在使用的 Json.NET 端口 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;
}
如果您不想要这个,您将需要子类化这个合同解析器并纠正行为:
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;
}
}
然后序列化如下:
// 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);
我想忽略 json 序列化中的序列化私有字段,但似乎 [JsonIgnore]
仅适用于 public
字段,不适用于 [SerializeField]
private
个字段。还有其他方法可以忽略这些字段吗?
这是一个例子class:
using UnityEngine;
using Newtonsoft.Json;
[JsonObject(MemberSerialization.OptIn)]
public class ExampleObject : MonoBehaviour {
[JsonProperty]
private string property = "Property";
[JsonIgnore]
[SerializeField]
private string ignored = "Ignored";
}
输出
{"property":"Property","ignored":"Ignored"}
它仍然将 ignored
字段序列化为 json,即使我在 class 上使用 [JsonObject(MemberSerialization.OptIn)]
并且在 [=16 上使用 [JsonIgnore]
=] 字段.
MemberSerialization.OptIn
说
"Only members marked with
JsonPropertyAttribute
orSystem.Runtime.Serialization.DataMemberAttribute
are serialized"
,但它似乎还包括 SerializeField
属性。
编辑:我正在使用 JilleJr Newtonsoft.Json-for-Unity
(github link) with JilleJr Newtonsoft.Json-for-Unity.Converters
(github link)
问题是您正在使用的 Json.NET 端口 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; }
如果您不想要这个,您将需要子类化这个合同解析器并纠正行为:
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;
}
}
然后序列化如下:
// 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);