4

WebApi には、HttpResponseMessage を返すメソッドがいくつかあります。応答タイプが不明であるため、次のようなものを使用して HelpPageConfig に登録する必要があります

config.SetActualResponseType(typeof(X), "SomeController", "GetX");

[ActualResponse(typeof(X)]少し乱雑なリスト内のすべてを参照する大きなレジストリ オブジェクトを作成しないように、コントローラーが宣言されているカスタム属性を使用してこれらを登録したいと思います。

SetActualResponseType を自動的に呼び出すことができるように、登録済みのコントローラーとアクション、およびそれらの属性のリストを取得するために構成を調べるにはどうすればよいですか?

4

1 に答える 1

0

mvc と web api のソースを調査しましたが、そのようなロジックを挿入できる場所が見つかりませんでした。mvc/web api でのアクション メソッドの検索は簡単な作業ではありません。これは、メソッドがアクション メソッドであるか通常のメソッドであるか (登録されたルートなどに基づく) を判断するチェックが多数あるためです。あなたの場合、カスタム ActualResponse 属性を持つメソッドのみを処理する必要がありますよね? したがって、反射でそれを行うことができます。もちろん、そのようなものは高速ではなく、パフォーマンスに影響を与えます。しかし、そのようなロジックを Application_Start で一度実行すれば、それは許容できると思います。

実装例:

public static class ActionMethodsRegistrator
{
    private static readonly Type ApiControllerType = typeof(IHttpController);

    public static void RegisterActionMethods(YourCustomConfig config)
    {
        // find all api controllers in executing assembly            
        var contollersTypes = Assembly.GetExecutingAssembly().GetTypes()
            .Where(foundType => ApiControllerType.IsAssignableFrom(foundType));

        // you may also search for controllers in all loaded assemblies e.g.
        // var contollersTypes = AppDomain.CurrentDomain.GetAssemblies()
        //    .SelectMany(s => s.GetTypes())
        //    .Where(foundType => ApiControllerType.IsAssignableFrom(foundType));                

        foreach (var contollerType in contollersTypes)
        {
            // you may add more restriction here for optimization, e. g. BindingFlags.DeclaredOnly
            // I took search parameters from mvc/web api sources.
            var allMethods = contollerType.GetMethods(BindingFlags.Instance | BindingFlags.Public);

            foreach (var methodInfo in allMethods)
            {
                var actualResponseAttrubute = methodInfo.GetCustomAttribute<ActualResponseAttribute>();
                if (actualResponseAttrubute != null)
                {                       
                    config.SetActualResponseType(actualResponseAttrubute.Type, contollerType.Name, methodInfo.Name);                        
                }
            }
        }
    }
}

Global.asax ファイル:

    protected void Application_Start()
    {
        //....
        YourCustomConfig config = InitializeConfig();
        ActionMethodsRegistrator.RegisterActionMethods(config);
    }
于 2014-08-28T19:39:59.233 に答える