2012-05-08 3 views
2

나는이처럼 보이는 포장 목록이 있습니다JSON.NET 컬렉션 타입 객체를 ISerializable을 무시

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

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

내가 할 수있는 :

[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) 
    } 
} 

내가 이런 고객 클래스의 필드 인스턴스를 포함을 고객을 직렬화하지만 OrderManagerISerializable 인터페이스는 무시됩니다. OrderManager에서 JsonObject 속성을 제거하면 (ISerializable이 사용되지 않을 가능성이 있음) OrderManager은 배열로 처리되고 ISerializable 인터페이스는 여전히 무시됩니다. 내 포장 컬렉션 타입 Order이며 내 AddOrder 방법은 OrderInfo에 소요 JSON.NET cannot deserialize a wrapped collection

때문에, 정말 ICollection<Order>를 노출 작동하지 않습니다

나는 IEnumerable 대신 ICollection를 사용했습니다. 어쨌든 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 문서 사이트에서이 내용을 조금 읽었습니다. 충돌이 있는지 궁금합니다. '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 구현.