参考/外部装配中的MapMvcAttributeRoutes

时间:2017-12-18 03:37:53

标签: c# .net asp.net-mvc attributerouting

我使用动态加载的程序集作为MVC控制器(插件/附加框架)的源。我找不到在引用的程序集中映射控制器的属性路由的方法。

我尝试从引用的程序集中调用MapMvcAttributeRoutes(就像建议的文章可以在Web API中使用一样)但是没有用。

如何在引用的程序集中映射控制器的属性路由?

编辑:

我有一个主MVC应用程序,它从文件加载程序集。这些程序集的结构如下:

Add-On Assembly Structure

我扩展了用于创建控制器和查找视图的代码,但是我找不到如何处理(映射)外部程序集中指定的RouteAttribute的说明,如下所示:

[RoutePrefix("test-addon")]
public class MyTestController : Controller
{
    [Route]
    public ActionResult Page()
    {
        return View(new TestModel { Message = "This is a model test." });
    }
}

1 个答案:

答案 0 :(得分:0)

我设法找到了解决方案:手动将路径属性解析为路线词典。可能不是百分之百正确,但这似乎到目前为止工作:

public static void MapMvcRouteAttributes(RouteCollection routes)
{
    IRouteHandler routeHandler = new System.Web.Mvc.MvcRouteHandler();

    Type[] addOnMvcControllers =
        AddOnManager.Default.AddOnAssemblies
            .SelectMany(x => x.GetTypes())
            .Where(x => typeof(AddOnWebController).IsAssignableFrom(x) && x.Name.EndsWith("Controller"))
            .ToArray();

    foreach (Type controller in addOnMvcControllers)
    {
        string controllerName = controller.Name.Substring(0, controller.Name.Length - 10);
        System.Web.Mvc.RoutePrefixAttribute routePrefix = controller.GetCustomAttribute<System.Web.Mvc.RoutePrefixAttribute>();
        MethodInfo[] actionMethods = controller.GetMethods();
        string prefixUrl = routePrefix != null ? routePrefix.Prefix.TrimEnd('/') + "/" : string.Empty;

        foreach (MethodInfo method in actionMethods)
        {
            System.Web.Mvc.RouteAttribute route = method.GetCustomAttribute<System.Web.Mvc.RouteAttribute>();

            if (route != null)
            {
                routes.Add(
                    new Route(
                        (prefixUrl + route.Template.TrimStart('/')).TrimEnd('/'),
                        new RouteValueDictionary { { "controller", controllerName }, { "action", method.Name } },
                        routeHandler));
            }
        }
    }
}

看似过度的修剪实际上只是为了确保在任何条件下都没有任何额外的'/'在开始,中间或结束。