Ambiguous controllers

Last post 09-18-2008 1:09 AM by wenhx. 5 replies.

Sort Posts:

  • Ambiguous controllers

    12-14-2007, 4:12 PM
    • Member
      76 point Member
    • RRidge
    • Member since 08-08-2003, 2:03 PM
    • Posts 20

    I've been playing with nesting views and controllers in subdirectories for more fine grained partitioning, I've discovered through reflector I can do a RenderView("~/Views/SomeDirectory/SomeOtherDirectory/File.aspx") and it overrides your default search in Views and then in Views/Shared.  I am pleased.

    However, I am having some difficulty with controllers.  I see that you're expecting Foo followed by Controller (such as FooController), but your search is through the entire assembly, such that if I have Controllers/FooController and Controllers/SomeDirectory/FooController it sees two FooControllers and throws an ambiguous controller invalid operation exception.  The exception's suggested action is to disambiguate the controllers by using the full namespace in the route.  When I attempt to set a route with a fully qualified controller default property, I end up getting an invalid operation exception suggesting that the controller cannot be found, for example controller = "Company.MySite.Controllers.Foo.BarController", when that is indeed the correct fully qualified type name.  Apparently I'm missing something important here, but I'm not sure what.

    I like the story for dealing with nesting views and being able to supply a virtual path, but it seems like something is missing for dealing with nested controllers in subdirectories...  I'm not entirely clear on what I want here, but I do know that having an explosion of classes directly under Controllers and Views seems like it would lead to some management issues with a sizable site...

     

  • Re: Ambiguous controllers

    12-14-2007, 7:31 PM
    • Member
      574 point Member
    • abombss
    • Member since 06-27-2006, 4:13 PM
    • Chicago, IL
    • Posts 164

    For now you need a custom controller factory.

    The MVCContrib project has some examples of how to build one. 

    It would be great if we could get support for partitioning areas of an application with namespaces or something like the monorail "Area" parameter on the ControllerDetailsAttribute 

    Adam 


     

    Adam Tybor -- abombss.com
  • Re: Ambiguous controllers

    12-14-2007, 8:59 PM
    Answer
    • Contributor
      5,773 point Contributor
    • Haacked
    • Member since 09-17-2003, 2:43 PM
    • Posts 388

    This is definitely a problem. 

    We're planning to address this with the ability to disambiguation of controller selection by allowing you to specify namespaces.

    Phil Haack (http://haacked.com/)
    Senior Program Manager, Microsoft

    What wouldn’t you do for a Klondike bar?
  • Re: Ambiguous controllers

    12-14-2007, 9:15 PM
    Answer
    • Member
      349 point Member
    • slynch
    • Member since 09-03-2002, 4:18 PM
    • Michigan
    • Posts 71

    The following should work till they have the GetControllerType of the MvcHandler class take namespaces into account, at which time I suggest you forget these use theirs. 

    	
    public class MvcRouteHandlerNS : MvcRouteHandler
    	{
    		protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    		{
    			return new MvcHandlerNS()
    			{
    				RequestContext = requestContext
    			};
    		}
    	}
    	public class MvcHandlerNS: MvcHandler
    	{
    		protected static object _customLock = new object();
    		protected static Dictionary<string, Type> _typeCache = new Dictionary<string, Type>();
    
    		protected override Type GetControllerType(string controller)
    		{
    			IDictionary<string,object> routeDefaults = this.RequestContext.RouteData.Values;
    			if (routeDefaults.Keys.Contains("ns"))
    			{
    				string typeName = String.Format("{0}.{1}Controller", routeDefaults["ns"], controller);
    				Type controllerType = null;
    				lock (_customLock)
    				{
    					if (_typeCache.ContainsKey(typeName))
    						controllerType = _typeCache[typeName];
    
    
    					if(controllerType == null)
    {
    controllerType = Type.GetType(typeName); if (controllerType!=null) { _typeCache.Add(typeName, controllerType); }
    }
    }
    if(controllerType!=null)
    return controllerType; } return base.GetControllerType(controller); } }
     And in the glabal.asax class use
    RouteTable.Routes.Add(new Route
    {
    	Url = "SomeDirectory/[action]/[id]",//Base path needs to be specified
    	Defaults = new { controller = "Bar", ns = "Company.MySite.Controllers.Foo", action = "Index", id = (string)null },
    	RouteHandler = typeof(MvcRouteHandlerNS)
    });
    

    Though personally, I would just name my somedirectory/foobarcontroller SomeDirectoryFooBarController and SomeOtherDirectoryFooBarController, and forget I ever saw this code. At least until they add support for namespaces in the controllers.

    Edit: Especially since it looks like they are looking into it already.

    Sean Lynch - Blog
  • Re: Ambiguous controllers

    12-15-2007, 3:43 PM
    • Member
      574 point Member
    • abombss
    • Member since 06-27-2006, 4:13 PM
    • Chicago, IL
    • Posts 164

    Thanks Sean... I meant to say a RouteHandler but wrote about a ControllerFactory... Smile 

    Adam Tybor -- abombss.com
  • Re: Ambiguous controllers

    09-18-2008, 1:09 AM
    • Member
      2 point Member
    • wenhx
    • Member since 01-11-2007, 10:17 PM
    • Posts 1


     

Page 1 of 1 (6 items)