8

コントローラー アクションをインターフェイスにバインドしようとしていますが、既定のバインド動作を維持しています。

public class CoolClass : ISomeInterface
{
    public DoSomething {get;set;} // ISomeInterface
}

public class DosomethingController : ApiController
{
    public HttpResponseMessage Post(ISomeInterface model)
    {
        // do something with model which should be an instance of CoolClass
    }
} 

私のサービスの消費者は CoolClass について何も知らないので、渡す Json に「$type」を追加させることは、私の考えではハックです。サービスで対応できるようにしたいです。アクション パラメーターとして CoolClass を指定すると、正常に動作します。

編集:だから私はここで私の質問に対する部分的な解決策を見つけましたASP.NET Web APIアクションメソッドパラメーターの依存性注入ですが、フォローアップの問題があります。そのソリューションは、インターフェイス プロパティを解決しません。以下の私の例を参照してください。

IConcreteClass は解決されますが、ISubtype は解決されません。

public class SubConcreteClass : ISubtype
{
    // properties
}

public class ConcreteClass : IConcreteClass
{
    public ISubtype Subtype {get;set;}
}

メディア フォーマッタは、IConcreteClass で型を解決できることを確認すると、ストリーム全体を読み取ります。したがって、インターフェイス メンバーを解決する機会はないと思います。

4

2 に答える 2

13

したがって、これが他の誰かに役立つ場合に備えて、思いついた解決策を投稿します。

前述したように、アクション メソッドのインターフェイス パラメーターは DI を使用して解決できます。ただし、そのオブジェクトのインターフェイス メンバーは別の方法で処理する必要があります。

インターフェイス プロパティを装飾するために、単一のエンティティ型とコレクション型の 2 種類の Json コンバーターを作成しました。

アクション インターフェイス パラメータとして解決する必要があるクラスを次に示します。

public class CreateEnvelopeModel : ICreateEnvelopeCommand
{
    [JsonConverter(typeof(EntityModelConverter<CreateEmailModel, ICreateEmailCommand>))]
    public ICreateEmailCommand Email { get; set; }
    [JsonConverter(typeof(CollectionEntityConverter<CreateFormModel, ICreateFormCommand>))]
    public IList<ICreateFormCommand> Forms { get; set; }
}

これがコントローラーアクションメソッドです

public HttpResponseMessage PostEnvelope(ICreateEnvelopeCommand model)
{
    // do stuff
}

これが2つのjsonコンバーターです

public class EntityModelConverter<T, Tt> : JsonConverter where T : Tt
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Tt));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return serializer.Deserialize<T>(reader);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value, typeof(T));
    }
}

public class CollectionEntityConverter<T, Tt> : JsonConverter where T : Tt
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IList<Tt>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        IList<Tt> items = serializer.Deserialize<List<T>>(reader).Cast<Tt>().ToList();
        return items;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value, typeof(IList<T>));
    }
}
于 2013-08-28T14:20:02.043 に答える