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 回答