4

次のようなラップされたリストがあります。

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

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

ICollection代わりに使用してみましたIEnumerableJSON.NETはラップされたコレクションを逆シリアル化できません

ラップされたコレクションの型が で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;          
}
4

1 に答える 1

3

この答えは遅いかもしれませんが:

これは、の継承をIEnumerableチェックする前にの継承をチェックするためISerializable、最初にEnumerableインターフェイスを使用してオブジェクトをプルするためです。

このオーバーライドを使用して継承する独自のコントラクトリゾルバーを実装することにより、この動作をオーバーライドできますDefaultContractResolver

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

        return base.CreateContract(objectType);
    }

できればいくつかのより良いロジックを使用しますが、これはルートで、最初にISerializable実装を実装ISerializableして使用するオブジェクトを引き起こします。IEnumerable

于 2012-10-31T21:52:56.050 に答える