本文介绍了序列化对象时有条件地忽略嵌套属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 公共类消息{公共字符串Content {get;放;}公共IEnumerable< Attachment>附件{放;}}公共类附件{公共字符串Base64Content {get;放;}公共字符串FileName {get;放;}} 

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

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

是否有一种编写 ContractResolver 类的方法,该类可让我在序列化 Message 对象时忽略 Base64Content 属性?

解决方案

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

>

 公共类CustomPropertiesContractResolver:DefaultContractResolver{私有HashSet< string>_propertySet;公共CustomPropertiesContractResolver(IEnumerable< string> propertyNames){如果(propertyNames!= null){_propertySet =新的HashSet< string>(propertyNames,StringComparer.OrdinalIgnoreCase);}}受保护的替代List< MemberInfo>GetSerializableMembers(Type objectType){列表< MemberInfo>serializableMembers = null;var allMembers = base.GetSerializableMembers(objectType);如果(_propertySet!= null& _amp; _propertySet.Count> 0){serializableMembers = allMembers.Where(m =>!_propertySet.Contains(m.Name)).ToList();}返回serializableMembers!= null&&serializableMembers.Count>0?serializableMembers:allMembers;}} 

使用方式:

  IEnumerable< string>属性= null;如果(条件){属性=新的List< string>{"Base64Content"};}var settings = new JsonSerializerSettings(){ContractResolver =新的CustomPropertiesContractResolver(属性)};var serializedStr = JsonConvert.SerializeObject(消息,设置); 

I'm struggling with conditionally serializing a property of an object that is a property of another object itself. Consider the following class structure:

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; }
}

In some scenarios I want to serialize everything in the Message class, including all Attachment objects and its properties. This can be done by using a simple JsonConvert.SerializeObject(). If I always wanted to ignore the Base64Content property, I could just add a '[JsonIgnore]' attribute on that property. However, there are some scenarios in which I want the Base64Content serialized, and in others I don't.

I though about creating a custom ContractResolver that ignores the Attachments property of the Message object. But of course, this ignores the whole list of Attachment objects and not just the Base64Content property.

Is there a way of writing a ContractResolver class that lets me ignore the Base64Content property when serializing the Message object?

解决方案

Just create a custom contract resolver which excludes the properties passed to it while serializing and pass the Base64Content property in it conditionally.

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;
    }
}

use it like:

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);

这篇关于序列化对象时有条件地忽略嵌套属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 10:10