T4MVC @Url.Action(MVC.Controller.Action()) Renders "?Area=" Parameter in QueryString
Asked Answered
B

3

21

I am rendering a menu from a Partial Action directly to the layout, using:

@Html.Action(MVC.Menu.Index())

This action, determines which Menu partial to render. For instance, a public menu partial. Within these partials, I am also using T4MVC to render the links:

<ul id="navHolder">
<li class="level1">
    <ul class="mainMenu">
        <li><b>@Html.ActionLink("Welcome", MVC.Home.Index())</b>
           ... 

For some reason, the Urls rendered by T4MVC include "?Area=" at the end:

 <ul id="navHolder">
    <li class="level1">
        <ul class="mainMenu">
            <li><b><a href="/home/index?Area=">Welcome</a></b>
               ...

I have NO areas in my project and I have turned the "IncludeAreasToken" setting to false. Oddly, this only happens if I render the partial using "@Html.Action" -- if I pull it in as "@Html.Partial" the parameter isn't rendered and the link is clean and correct. (I don't want to render it as a partial though, so please don't offer that as a suggestion ;)

Anyone out there run into this before?

Breastsummer answered 20/7, 2011 at 0:32 Comment(0)
O
10

Something strange is going on here, and I wonder if there is some kind of MVC bug at the root. Even without using T4MVC, this happens if you write:

@Html.ActionLink("Welcome", "Index", "Home", new { Area = "" }, null)

In a regular view, this doesn't generate the bogus ?Area=, while in a Html.Action call it does. I need to ask someone on the team.

For now, you can workaround by deleting this line (around line 310) in t4mvc.tt:

<# if (MvcVersion >= 2) { #>result.RouteValueDictionary.Add("Area", area ?? "");<# } #> 
Only answered 20/7, 2011 at 6:23 Comment(5)
I just added a check to see if the area was supplied, if so I add it to the dictionary: if (!String.IsNullOrWhiteSpace(area)) {result.RouteValueDictionary.Add("Area", area ?? "");}Sterne
@BradR: the problem with this change is that I think it's not always correct. When you're in an Area view and you're trying to generate a link to a top level (non-Area) view, then passing an empty area is the correct thing to do to 'escape' the current area. But with your check that won't happen.Only
It turns out that MVC only generates the bogus token if the app doesn't have any areas. So we should just fix T4MVC to only add this token if the app uses areas.Only
@DavidEbbo has this checking been implemented? I'm getting the same issue with the latest T4MVCGasp
No, but there is a simpler workaround here: mvccontrib.codeplex.com/workitem/7154Only
T
30

I solve this issue in a very easy way, simply by adding to all routes that are not in area empty area route like this:

routes.MapRoute(
"Default",
"{controller}/{action}/{i​d}",
new { controller = "Home", action = "Index", area = "", id = UrlParameter.Optional });
Typical answered 19/12, 2011 at 11:21 Comment(2)
Just tested this and it seems like the easiest solution - just add an area of String.Empty to the default route and all the URLs generate correctly.Sterne
This doesn't work if you use attribute routing in your project. See my answer which I copid from mvccontrib archive, workitem 7154 because you cannot find it easily on the archived Codeplex site now.Unreserve
O
10

Something strange is going on here, and I wonder if there is some kind of MVC bug at the root. Even without using T4MVC, this happens if you write:

@Html.ActionLink("Welcome", "Index", "Home", new { Area = "" }, null)

In a regular view, this doesn't generate the bogus ?Area=, while in a Html.Action call it does. I need to ask someone on the team.

For now, you can workaround by deleting this line (around line 310) in t4mvc.tt:

<# if (MvcVersion >= 2) { #>result.RouteValueDictionary.Add("Area", area ?? "");<# } #> 
Only answered 20/7, 2011 at 6:23 Comment(5)
I just added a check to see if the area was supplied, if so I add it to the dictionary: if (!String.IsNullOrWhiteSpace(area)) {result.RouteValueDictionary.Add("Area", area ?? "");}Sterne
@BradR: the problem with this change is that I think it's not always correct. When you're in an Area view and you're trying to generate a link to a top level (non-Area) view, then passing an empty area is the correct thing to do to 'escape' the current area. But with your check that won't happen.Only
It turns out that MVC only generates the bogus token if the app doesn't have any areas. So we should just fix T4MVC to only add this token if the app uses areas.Only
@DavidEbbo has this checking been implemented? I'm getting the same issue with the latest T4MVCGasp
No, but there is a simpler workaround here: mvccontrib.codeplex.com/workitem/7154Only
U
0

Copied from workitem 7154 comments is a solution provided by @DavidEbbo:

A simpler workaround is to add a bogus area to your site. e.g.\n\n- Right click Project and choose Add / Area. Name it 'Dummy' (or whatever)\n- You can delete everything in there except for the DummyAreaRegistration.cs file

Make sure you have the AreaRegistration.RegisterAllAreas(); call in your Global.asax

This also works with attribute routing in place.

Unreserve answered 8/4, 2021 at 10:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.