从 JSON 序列化中排除可执行属性

本文关键字:可执行 属性 排除 JSON 序列化 | 更新日期: 2023-09-27 18:32:49

我正在使用Newtonsoft.Json来序列化缓存的值,我想知道是否有办法以与从序列化中排除方法相同的方式排除可执行属性?最好是一种全局设置它的方法,这样我就不需要用属性标记数百个属性(我首先必须在数千个属性中找到)。

代码:

[Serializable]
public class Item
{
    public long Id { get; set; }
    public string Name { get; set; }
    public List<Image> Images { get; set; }
    public Image PrimaryImage { get { return Images[0]; } }
}
[Serializable]
public class Image
{
    public long Id { get; set; }
    public string FileName { get; set; }
}

错误:

Error getting value from 'PrimaryImage' on 'Item'.
at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)

我还要提到 PrimaryImage 中的逻辑已简化,因此解决方案是不要跳过使用该属性。这似乎是属性的一种非常常见的用法,所以我觉得很奇怪,它还没有处理它。

从 JSON 序列化中排除可执行属性

尝试以下代码(仅序列化 get-set 属性):

public static class NewtonsoftDefaultSettings
{
    public static JsonSerializerSettings CreateRelease()
    {
        return Create(Formatting.None);
    }
    public static JsonSerializerSettings CreateDebug()
    {
        return Create(Formatting.Indented);
    }
    private static JsonSerializerSettings Create(Formatting formatting)
    {
        return new JsonSerializerSettings
        {
            Formatting = formatting,
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
            ContractResolver = new MyContractResolver()
        };
    }
}
internal class MyContractResolver : DefaultContractResolver
{
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        var members = base.GetSerializableMembers(objectType).Cast<PropertyInfo>().ToList();
        members.RemoveAll(x => !x.CanRead || !x.CanWrite);
        return members.Cast<MemberInfo>().ToList();
    }
}

最后:

var str = JsonConvert.SerializeObject(value, NewtonsoftDefaultSettings.CreateDebug());