2017-08-31 63 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); 
相關問題