2013-05-20 56 views
1

我想序列化僅更改的屬性。我被設法做到了根類型,但它包含對其他要被序列化的對象(甚至可能是相同類型)的引用。繼承DefaultContractResolver並以不同的方式處理參考實體

這是我的界面和ContractResolver:

public interface ISelectiveJsonSerialize 
{ 
    IList<string> PropertiesToSerialize { get; } 
} 

public class JsonSelectiveSerializeContractResolver : DefaultContractResolver 
{ 
    private readonly IList<string> _propertiesToSerialize; 

    public JsonSelectiveSerializeContractResolver(IList<string> propertiesToSerialize) 
    { 
     _propertiesToSerialize = propertiesToSerialize; 
    } 

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     return base.CreateProperties(type, memberSerialization).Where(p => _propertiesToSerialize.Contains(p.PropertyName)).ToList(); 
    } 
} 

酒店PropertiesToSerialize將有接收的值的屬性名稱的列表。

這是我如何序列化:

 string result = ""; 
     if (val is ISelectiveJsonSerialize) 
     { 
      // Don't serialize all properties 
      var resolver = new JsonSelectiveSerializeContractResolver(((ISelectiveJsonSerialize)val).PropertiesToSerialize); 
      var settings = new JsonSerializerSettings { ContractResolver = resolver }; 
      result = JsonConvert.SerializeObject(val, Formatting.None, settings); 
     } 
     else 
     { 
      // Default serialization 
      result = JsonConvert.SerializeObject(val); 
     } 

     return result; 

這是一個類型的一個例子,我可以序列:

public class Category : BaseType 
{ 
    private string _name; 
    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      _name = value; 
      PropertiesToSerialize.Add("Name"); 
     } 
    } 

    private Category _category; 
    public Category Category 
    { 
     get { return _category; } 
     set 
     { 
      _category = value; 
      PropertiesToSerialize.Add("Category"); 
     } 
    } 
} 

正如你所瞭解,如果我只設置一個類別爲我的根類型,它有一個名稱,它不會序列化名稱,因爲根目錄PropertiesToSerialize不包含「名稱」,如果它願意,它會序列化根實體的空名稱。

幫助?

+0

我正在考慮ContractResolver與JsonConverter之間的某種組合,但不知道如何去做。 –

+0

你有沒有考慮過使用視圖模型? –

+0

查看模型將如何不同?這些類不是實體,它們可以視爲視圖模型,我可以隨他們做我想做的任何事情,這就是爲什麼添加要更改序列化屬性的列表。那麼視圖模型如何幫助我? –

回答

0

您可以掛接到Json.NET的conditional property serialization功能加入測試,以確定是否給定的屬性已序列化之前被修改:

public class JsonSelectiveSerializeContractResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     var property = base.CreateProperty(member, memberSerialization); 

     var shouldSerialize = property.ShouldSerialize; 
     var name = property.PropertyName; 
     property.ShouldSerialize = (o) => 
     { 
      var selectiveSerialize = o as ISelectiveJsonSerialize; 
      if (selectiveSerialize != null) 
      { 
       if (!selectiveSerialize.PropertiesToSerialize.Contains(name)) 
        return false; 
      } 
      return shouldSerialize == null || shouldSerialize(o); 
     }; 

     return property; 
    } 
} 

樣品fiddle