2012-05-08 9 views
2

にISerializableを無視します:私はこのような顧客のクラスにフィールドインスタンスを含めるJSON.NETが、私はこのようになります包まれたリスト持っているコレクション型のオブジェクト

[JsonObject(MemberSerialization.Fields)] 
public class OrderManager : IEnumerable<Order>, ISerializable 
{ 
    public OrderManager() 
    { } 

    private List<Order> orders = new List<Order>(); 

    public void AddOrder(OrderInfo orderInfo) 
    { 
     // do the work of making an order object from an OrderInfo. 
     // Add the new order object to the private list of orders 
     // orders.Add(order); 
    } 

    public IEnumerator<Order> GetEnumerator() 
    { 
     return orders.GetEnumerator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return orders.GetEnumerator(); 
    } 

    public OrderManager(SerializationInfo info, StreamingContext context) 
    { 
     // do custom serialization work here (never gets hit) 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     // do custom serialization work here (never gets hit) 
    } 
} 

を:

[JsonObject(MemberSerialization.Fields)] 
public class Customer 
{ 
    public Customer() 
    { } 

    private OrderManager _orders 
     = new OrderManager(); 
    public OrderManager Orders 
    { 
     get { return _orders; } 
     set { _orders = value; } 
    } 
} 

私がすることができます顧客をシリアル化しますが、OrderManagerISerializableインターフェイスは無視されます。 OrderManager(おそらくISerializableが使用されない原因)からJsonObject属性を削除すると、OrderManagerは配列として扱われ、ISerializableインターフェイスは引き続き無視されます。

私はICollection代わりのIEnumerableを使用してみました: JSON.NET cannot deserialize a wrapped collection

私のラップコレクションはタイプOrderのものであり、私のAddOrder方法がOrderInfoを取り込み、それは本当にICollection<Order>を公開するために動作しませんので。いずれにしても、ISerializableインターフェイスは無視されました。

回避策はありますか?

更新

ちょうど私がIgnoreSerializableInterfaceがfalseに設定されていない明確にします。

private JsonSerializer GetSerializer() 
{ 
    var serializer = new JsonSerializer(); 

    serializer.TypeNameHandling = TypeNameHandling.Auto; 
    serializer.TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; 

    var contractResolver = new DefaultContractResolver(true); 
    contractResolver.IgnoreSerializableAttribute = false; 
    contractResolver.IgnoreSerializableInterface = false; 

    serializer.ContractResolver = contractResolver; 

    serializer.PreserveReferencesHandling = PreserveReferencesHandling.All; 
    serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 

    return serializer;   
} 
+0

'_orders 'のインスタンス化を' Customer'コンストラクタに移そうとしましたか? – scottm

+0

ちょうどそれを試みました。 OrderManagerのJsonObject属性の有無にかかわらず、ISerializableは無視されました。 – mbursill

+0

'[Serializable]'属性を追加し、 '[JsonObject()]'のコンストラクタを空にするだけでは不思議です。私はこれをJSON.NETのdocサイトで少し読んでいましたが、何が起きているのか不思議です。 'Serializable'属性は' JsonObject(MemberSerialization.Fields) 'と同じ効果があります。 –

答えて

3

この回答は遅れるかもしれませんが:

それはそれは、最初のオブジェクトを引き出すために列挙インターフェイスを使用しますISerializableの相続をチェックする前にIEnumerableの継承を調べるので、これがあります。

あなたはこのオーバーライドでDefaultContractResolverから継承し、独自の契約リゾルバを実装することで、この動作を無効にすることができます:好ましくは、いくつかのより良いロジックと

protected override JsonContract CreateContract(Type objectType) 
    { 
     if (typeof(ISerializable).IsAssignableFrom(objectType)) 
      return CreateISerializableContract(objectType); 

     return base.CreateContract(objectType); 
    } 

が、ルートで、これはISerializableIEnumerableを実装するオブジェクトを使用するようになります最初にISerializable実装を実装します。

関連する問題