AreaAttribute?

Apr 15, 2011 at 8:24 PM

I have run across an issue with this library when I have controllers with the same name but in different namespaces.  For example:

SampleProject.Controllers.HomeController
and
SampleProject.Controllers.Admin.HomeController

The routes generated by the library are perfectly fine, but the issue is that the url generation mechanism of ASP NET MVC ignores the "namespaces" data token completely.  this means that all of the following methods (and all of those like them) will generate a url to the first HomeController, and never the second:

 

HtmlHelper.Action("Index", "HomeController");
HtmlHelper.Action("Index", "HomeController", new { namespaces = new [] {"SampleProject.Controllers.Admin"} });
HtmlHelper.Action("Index", "HomeController", new { namespaces = new [] {"SampleProject.Controllers"} });

 

This issue comes about because the "namespaces" datatoken is supported by the inbound routing system, but not the outbound system.

My idea is to add an AreaAttribute that would allow you to tag a controller with an area name, which would then be added to the datatokens by MvcCodeRouting.  That would allow you to generate urls to controllers that have the same name by differentiating them by areas.  So the declaration of the admin HomeController would look like this:

 

[Area("Admin")]
public class HomeController : Controller {...}

 

and the call to generate a url would look like this:

HtmlHelper.Action("Index", "HomeController", new { area = "Admin" });

 

The attribute would be optional, so existing projects that use MvcCodeRouting would be unaffected.  What do you think?  I could probably come up with a patch to implement this if there are no objections.

Thanks!  -tyler burd

Coordinator
Apr 15, 2011 at 9:04 PM

Hi tyler,

This is a known unresolved issue. Your solution looks very easy to implement and compatible with ASP.NET MVC Areas (i.e. links with an "area" value).
However, mixing namespaces and areas sounds confusing. Also, I created this library as an alternative to areas (although it's useful even if you have all your controllers in the same namespace), so even talking about areas makes my stomach turn.

I'll think about this this weekend, my inclination is to try to do something with UrlHelper to make it namespace-aware.

Thanks for the feedback!
--
Max

Apr 15, 2011 at 9:18 PM

I'm right there with you on the stomach turning.  I guess that's why I'm using MvcCodeRouting!

I, too, spent some time with UrlHelper and other parts of the routing system.  I tried the following, just for your info:

  • Making the "area" datatoken automatically mirror the namespace of the controller.  This had the disadvantage of having to pass in the (sometimes very long) namespace with EVERY link.
  • Creating new helper methods that loop through the Routes collection trying to find the specific route to use based on the BaseRoute data token.  This had the disadvantage that these custom helper methods would always have to be used, rather than the standard helper methods that most developers will use.  Also, I had to add methods to my base Controller class (for RedirectToAction), UrlHelper, and HtmlHelper, so that was a lot of places to diverge from default functionality.

I've actually implemented my solution and it works, so I can give that to you as a patch if you desire.  One addition that would be nice would be to scan the controllers for conflicting names and throw an exception when they are not disambiguated with an AreaAttribute.  Something like this:
ConflictingControllerNamesException: "The controller SomeProject.Controllers.HomeController and SomeProject.Controllers.Admin.HomeController" have the same name; you should mark one of them with an AreaAttribute to disambiguate them.  See http://someDocsAboutthis.com for more information."

I totally understand if you choose not to go this route (no pun intended), though, so let me know what you come up with and what you decide!

Thanks!

-tyler

Coordinator
Apr 16, 2011 at 6:29 AM

Hey tyler,

I came up with a solution, can you help me test it?

The idea is that URL generation is implicitly namespace aware, e.g. 
Url.Action("", "Home") can return "/" or "/Admin/Home", depending on the current route.
You can also qualify the controller parameter, e.g. 
Url.Action("", "SampleProject.Controllers.Admin.Home")

Let me know what you think.

--
Max

Apr 18, 2011 at 8:49 PM

Hi Max.

I should have some time today to check it out; I'll let you know how it works for me!  And thanks for the effort to resolve this!

-tyler

May 16, 2011 at 5:36 PM

Hi Max,

Sorry it has taken me a while to get back to you; I began testing the library about a week ago, and I have discovered a new issue that I *think* is related to this change:

Before the change I had links and forms that were created like this:

@Html.ActionLink("Link Text", "ActionName")
@Html.BeginForm(new { action = "Submit" }) 

Those calls now just output empty strings in the href/action attributes.  I reverted to the old version of MvcCodeRouting and everything worked as expected.

Coordinator
May 16, 2011 at 6:38 PM
Tyler,
I don't have enough information to reproduce. Could you please send me
a project that reproduces the issue?
--
Max Toro



On Mon, May 16, 2011 at 1:36 PM, [email removed] wrote:
> From: tylerburd
>
> Hi Max,
>
> Sorry it has taken me a while to get back to you; I began testing the
> library about a week ago, and I have discovered a new issue that I *think*
> is related to this change:
>
> Before the change I had links and forms that were created like this:
>
> @Html.ActionLink("Link Text", "ActionName")
> @Html.BeginForm(new { action = "Submit" })
>
> Those calls now just output empty strings in the href/action attributes.  I
> reverted to the old version of MvcCodeRouting and everything worked as
> expected.
>
> Read the full discussion online.
>
> To add a post to this discussion, reply to this email
> ([email removed])
>
> To start a new discussion for this project, email
> [email removed]
>
> You are receiving this email because you subscribed to this discussion on
> CodePlex. You can unsubscribe or change your settings on codePlex.com.
>
> Please note: Images and attachments will be removed from emails. Any posts
> to this discussion will also be available online at codeplex.com
May 16, 2011 at 7:40 PM

Sample app created and attached to http://mvccoderouting.codeplex.com/workitem/276

Coordinator
May 16, 2011 at 10:54 PM
Fixed, if you build the latest revision it should work fine.