2017-08-31 24 views
1

我正在努力有条件地序列化另一个对象本身的属性的对象的属性。考虑下面的类结构:在序列化对象时有条件地忽略嵌套属性

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序列化,而在其他情况下,我不这样做。

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

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

+0

你能做出新的类,具有相同的结构,并通过[JsonIgnore]根据需要?然后将你现有的类串起来,如果你想要所有的序列化的**或**映射到你的新类并将其序列化,如果你只需要一些字段序列化。 – mjwills

+0

@mjwills可能是一个解决方案,但会引入很多(接近)重复的类,我希望以更清晰的方式解决问题。 – Froodooo

+0

您可能可以修改[Json.NET按深度和属性序列化]的答案(https://stackoverflow.com/q/36159424/3744182)。 – dbc

回答

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); 
相关问题