【问题标题】:Conditionally ignore nested property when serializing object序列化对象时有条件地忽略嵌套属性
【发布时间】:2017-08-31 10:13:42
【问题描述】:

我正在努力有条件地序列化一个对象的属性,该属性是另一个对象本身的属性。考虑以下类结构:

public class Message
{
    public string Content { get; set; }
    public IEnumerable<Attachment> Attachments { get; set; }
}

public class Attachment
{
    public string Base64Content { get; set; }
    public string FileName { get; set; }
}

在某些情况下,我想序列化 Message 类中的所有内容,包括所有 Attachment 对象及其属性。这可以通过使用简单的JsonConvert.SerializeObject() 来完成。如果我一直想忽略 Base64Content 属性,我可以在该属性上添加一个 '[JsonIgnore]' 属性。但是,在某些情况下我希望序列化 Base64Content,而在其他情况下我不希望。

我想创建一个忽略Message 对象的Attachments 属性的自定义ContractResolver。但当然,这会忽略 Attachment 对象的整个列表,而不仅仅是 Base64Content 属性。

有没有办法编写一个ContractResolver 类,让我在序列化Message 对象时忽略Base64Content 属性?

【问题讨论】:

  • 您能根据需要创建具有相同结构并使用 [JsonIgnore] 的新类吗?如果您希望将所有内容序列化映射到您的新类,然后序列化您现有的类,如果您只想序列化一些字段,则将其序列化。
  • @mjwills 这可能是一个解决方案,但会为我希望以更简洁的方式解决的问题引入很多(接近)重复的类。
  • 您也许可以调整来自Json.NET serialize by depth and attribute 的答案。

标签: c# serialization json.net


【解决方案1】:

只需创建一个自定义合同解析器,它会在序列化时排除传递给它的属性,并有条件地在其中传递Base64Content 属性。

public class CustomPropertiesContractResolver : DefaultContractResolver
{
    private HashSet<string> _propertySet;

    public CustomPropertiesContractResolver(IEnumerable<string> propertyNames)
    {
        if (propertyNames != null)
        {
            _propertySet = new HashSet<string>(propertyNames, StringComparer.OrdinalIgnoreCase);
        }
    }

    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        List<MemberInfo> serializableMembers = null;
        var allMembers = base.GetSerializableMembers(objectType);

        if (_propertySet != null && _propertySet.Count > 0)
        {
            serializableMembers = allMembers.Where(m => !_propertySet.Contains(m.Name)).ToList();
        }
        return serializableMembers != null && serializableMembers.Count > 0 ? serializableMembers : allMembers;
    }
}

像这样使用它:

IEnumerable<string> properties = null;
if (condition)
{
    properties = new List<string> { "Base64Content" };
}

var settings = new JsonSerializerSettings()
{
    ContractResolver = new CustomPropertiesContractResolver(properties)
};
var serializedStr = JsonConvert.SerializeObject(messages, settings);

【讨论】:

    猜你喜欢
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2013-04-07
    • 1970-01-01
    • 2019-07-24
    相关资源
    最近更新 更多