1

SelfHosted AspNet WebAPI にカスタム MediaTypeFormatter を実装しました。依存関係の解決に Unity.WebApi を使用しました。コントローラー クラスは、モデル クラスによって実装されたインターフェイスについてのみ認識しますが、リポジトリは、アクションの結果として具体的なモデルを提供します。

ここで説明されているように、カスタム MediaTypeFormatter は BufferedMediaTypeFormatter から継承されます: http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

問題は、このメディア タイプ フォーマッタが機能していないことです。コードをデバッグするために使用しても、ReadFormStream メソッドがヒットすることはありません。誰か知っていますか:

  1. 考えられる問題は何ですか?
  2. インターフェイスをモデル クラスにマッピングするために Unity コンテナーに指示する必要がありますか?
  3. カスタム メディア タイプ フォーマッタ内の依存関係リゾルバーへの参照を取得するにはどうすればよいですか?

以下は、フォーマッタを追加するコードです。

var config = new SelfHostConfiguration("https://xxx.xxx.xxx.xxx:xxxx/");
config.Formatters.Add(new EntityTypeFormatter());

以下は、EntityController のコードです。

    public class EntityController : ApiController
    {
        プライベート読み取り専用 IEntitiesRepository リポジトリ = null;

        public EntityController(IEntitiesRepository リポジトリ)
        {
            if (リポジトリ == null)
            {
                新しい ArgumentNullException("リポジトリ") をスローします。
            }

            this.repository = リポジトリ;
        }

        public IEnumerable<IEntity> Get()
        {
            return (IEnumerable<IEntity>)repository.Get();
        }
    }

以下は、EntityRepository のコードです。

    public class EntitiesRepository : IEntitiesRepository
    {
        public IEnumerable<IEntity> Get()
        {
            新しいエンティティを返す[]
            {
                新しいエンティティ
                {
                    Prop1 = "プロパティ 1 の値",
                    Prop2 = "プロパティ 2 の値",
                    Prop3 = "プロパティ 3 の値"
                }、
                新しいエンティティ
                {
                    Prop1 = "プロパティ 1 の値",
                    Prop2 = "プロパティ 2 の値",
                    Prop3 = "プロパティ 3 の値"
                }
            };
        }
        public IEntity Get (長い ID)
        {
            新しいエンティティを返す
                {
                    Prop1 = Convert.ToString(id),
                    Prop2 = "プロパティ 2 の値",
                    Prop3 = "プロパティ 3 の値"
                };
        }
    }

以下は、EntityMediaTypeFormatter クラスの実装です。

public class EntityMediaTypeFormatter : BufferedMediaTypeFormatter
    {
        public EntityMediaTypeFormatter()
            : ベース()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        }

        public override bool CanReadType(Type タイプ)
        {
            if (タイプ == null)
            {
                新しい ArgumentNullException("型") をスローします。
            }

            if (型は IEntity)
            {
                true を返します。
            }
            それ以外の場合 (type.IsGenericType)
            {
                戻り値 type.GenericTypeArguments.Single(a => a.GetType().Equals(typeof(IEntity))) != null;
            }

            false を返します。
        }
        public override bool CanWriteType(Type type)
        {
            if (タイプ == null)
            {
                新しい ArgumentNullException("型") をスローします。
            }

            if (型は IEntity)
            {
                true を返します。
            }

            false を返します。
        }

        パブリック オーバーライド オブジェクト ReadFromStream(Type タイプ、ストリーム readStream、HttpContent コンテンツ、IFormatterLogger formatterLogger)
        {
            if (type.IsInterface)
            {
                タイプ = GetConcreteType(タイプ);
            }

            return base.ReadFromStream(type, readStream, content, formatterLogger);
        }
        public override void WriteToStream(Type 型、オブジェクト値、ストリーム writeStream、HttpContent コンテンツ)
        {
            // 今のところ特別なことはありません...
            base.WriteToStream(タイプ、値、writeStream、コンテンツ);
        }

        private Type GetConcreteType(型 type)
        {
            //TODO: 具体的な型を取得するために DependencyResolver への方法を見つける必要があります
            typeof(エンティティ) を返します。
        }
    }

助けてくれてありがとう。

4

1 に答える 1