Categories of controllers in MVC Routing? (Duplicate Controller names in separate Namespaces)

冷暖自知 提交于 2019-12-04 13:44:58

I actually found it not even by searching, but by scanning through the ASP .NET forums in this question.

Using this you can have the controllers of the same name under any part of the namespace, so long as you qualify which routes belong to which namespaces (you can have multiple namespaces per routes if you need be!)

But from here, you can put in a directory under your controller, so if your controller was "MyWebShop.Controllers", you'd put a directory of "Shop1" and the namespace would be "MyWebShop.Controllers.Shop1"

Then this works:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        var shop1namespace = new RouteValueDictionary();
        shop1namespace.Add("namespaces", new HashSet<string>(new string[] 
        { 
            "MyWebShop.Controllers.Shop1"
        }));

        routes.Add("Shop1", new Route("Shop1/{controller}/{action}/{id}", new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(new
            {
                action = "Index",
                id = (string)null
            }),
            DataTokens = shop1namespace
        });

        var shop2namespace = new RouteValueDictionary();
        shop2namespace.Add("namespaces", new HashSet<string>(new string[] 
        { 
            "MyWebShop.Controllers.Shop2"
        }));

        routes.Add("Shop2", new Route("Shop2/{controller}/{action}/{id}", new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(new
            {
                action = "Index",
                id = (string)null
            }),
            DataTokens = shop2namespace
        });

        var defaultnamespace = new RouteValueDictionary();
        defaultnamespace.Add("namespaces", new HashSet<string>(new string[] 
        { 
            "MyWebShop.Controllers"
        }));

        routes.Add("Default", new Route("{controller}/{action}/{id}", new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
            DataTokens = defaultnamespace            
        });
    }

The only other thing is that it will reference a view still in the base directory, so if you put the view into directories to match, you will have to put the view name in when you return it inside the controller.

Dale Ragan

The best way to do this without any compromises would be to implement your own ControllerFactory by inheriting off of IControllerFactory. The CreateController method that you will implement handles creating the controller instance to handle the request by the RouteHandler and the ControllerActionInvoker. The convention is to use the name of the controller, when creating it, therefore you will need to override this functionality. This will be where you put your custom logic for creating the controller based on the route since you will have multiple controllers with the same name, but in different folders. Then you will need to register your custom controller factory in the application startup, just like your routes.

Another area you will need to take into consideration is finding your views when creating the controller. If you plan on using the same view for all of them, then you shouldn't have to do anything different than the convention being used. If you plan on organizing your views also, then you will need to create your own ViewLocator also and assign it to the controller when creating it in your controller factory.

To get an idea of code, there are a few questions I have answered on SO that relate to this question, but this one is different to some degree, because the controller names will be the same. I included links for reference.

Another route, but may require some compromises will be to use the new AcceptVerbs attribute. Check this question out for more details. I haven't played with this new functionality yet, but it could be another route.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!