Referenced/External 程序集中的 MapMvcAttributeRoutes
MapMvcAttributeRoutes in Referenced/External Assembly
我正在使用动态加载的程序集作为 MVC 控制器(plugin/add-on 框架)的来源。我找不到在引用的程序集中为控制器映射属性路由的方法。
我尝试从引用的程序集中调用 MapMvcAttributeRoutes(就像文章中建议的那样可以在 Web API 中工作)但是那没有用。
如何在引用的程序集中映射控制器的属性路由?
编辑:
我有一个从文件加载程序集的主 MVC 应用程序。这些程序集的结构如下:
我扩展了用于创建控制器和查找视图的代码,但我找不到关于如何处理外部程序集中指定的(映射)RouteAttribute
的说明,如下所示:
[RoutePrefix("test-addon")]
public class MyTestController : Controller
{
[Route]
public ActionResult Page()
{
return View(new TestModel { Message = "This is a model test." });
}
}
我设法找到了解决办法:手动将路由属性解析到路由字典中。可能没有做到 100% 正确,但到目前为止这似乎有效:
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));
}
}
}
}
看似多余的修剪实际上只是为了确保在任何情况下都不会在开头,中间或结尾有任何额外的'/'。
我正在使用动态加载的程序集作为 MVC 控制器(plugin/add-on 框架)的来源。我找不到在引用的程序集中为控制器映射属性路由的方法。
我尝试从引用的程序集中调用 MapMvcAttributeRoutes(就像文章中建议的那样可以在 Web API 中工作)但是那没有用。
如何在引用的程序集中映射控制器的属性路由?
编辑:
我有一个从文件加载程序集的主 MVC 应用程序。这些程序集的结构如下:
我扩展了用于创建控制器和查找视图的代码,但我找不到关于如何处理外部程序集中指定的(映射)RouteAttribute
的说明,如下所示:
[RoutePrefix("test-addon")]
public class MyTestController : Controller
{
[Route]
public ActionResult Page()
{
return View(new TestModel { Message = "This is a model test." });
}
}
我设法找到了解决办法:手动将路由属性解析到路由字典中。可能没有做到 100% 正确,但到目前为止这似乎有效:
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));
}
}
}
}
看似多余的修剪实际上只是为了确保在任何情况下都不会在开头,中间或结尾有任何额外的'/'。