简体   繁体   中英

MapMvcAttributeRoutes in Referenced/External Assembly

I am using dynamically loaded assemblies as a source for MVC Controllers (plugin/add-on framework). I can find no way to map the attribute routes for the Controllers in the referenced assembly.

I tried calling MapMvcAttributeRoutes from within the referenced assembly (like on article suggested would work in Web API) but that did not work.

How do I map attribute routes for Controllers in an referenced assembly?

EDIT:

I have a main MVC application which loads assemblies from a file. These assemblies are structured like so:

附加组件结构

I extended the code for creating a controller and finding a View but I can find no instructions on how to handle (map) RouteAttribute s specified in the external assembly like this:

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

I managed to find a solution: manually parse Route Attributes into the Route Dictionary. Probably not doing it 100% right but this seems to work so far:

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));
            }
        }
    }
}

The seemingly excessive trims are actually just to make sure that under no conditions are there any extra '/' at the start, middle or end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM