T4MVC #Url.Action(MVC.Controller.Action()) Renders "?Area=" Parameter in QueryString - asp.net-mvc

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>Welcome</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?

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

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 ?? "");<# } #>

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.

Related

How do I use an ActionLink with the RouteValueDictionary?

I'm trying to make my URL look like this:
http://domain.com/controller/action/123/SomeTextForSEO
I tried using an Action Link, but that appends ?company=SomeTextForSEO instead of the company name after a slash.
<%: Html.ActionLink("DomainList", "Index", "DomainList", new { id = item.CompanyID, company = item.CompanyDisplayName.Trim() }, new object { })%>
and now I think I need to use a RouteValueDictionary but I'm unsure of how to do this in ASP.NET syntax. Can someone point me in the right direction? The MSDN examples are insufficient.
If you go to global.asax.cs and add a new route similar to the existing default route with the pattern
"{controller}/{action}/{id}/{company}"
Before the default one, you should find that the link will generate correctly with your ActionLink call as-is.
I'm on a phone so I'd like to be more verbose (a route restriction would be a good idea to prevent this route interfering with the default), but the HTC keyboard is not code friendly ;)

ASP.NET MVC ActionLink outside area

A simple task in MVC, sometimes becomes a hard challenge.
Well,i have an Area called Admin. I've a page named "Forbidden" inside the Shared's directory in this area.
The goal is simple: I need to create an Html.ActionLink that generates a link to return to Home page which is OUTSIDE the Admin area.
So i try,<%= Html.ActionLink("Back","Index",new {controller="Home"})%>,and its generate :
http://localhost/Admin/Home/Index
Its wrong!I want:
http://localhost/Home/Index
How can i create a link from an area to the default controllers structure?
Try this :
<%= Html.ActionLink("Back", "Index", "Home", new { area = "" }, null) %>
When using Areas, you should always specify the area your are calling in your ActionLinks by adding a route value as above, If the link is outside the area (as in your case), just use an empty parameter for the area.
There's a nice extension that i find essential in any ASP.NET MVC project (T4MVC). It makes your ActionLinks look much cleaner and it protects them against errors.
So the above code will look something like this :
<%= Html.ActionLink("Back", MVC.Home.Index()) %>
and when using an area :
<%= Html.ActionLink("Some Link", MVC.Admin.SomeController.SomeAction()) %>
It's a part of the MvcContrib project on codeplex here
You should consider using it.

Troubles creating URLs in a VB.NET MVC view

I'm trying to write out animals from a database. All the samples I see for creating View pages have hard-coded "nodes" in the URLs. I can get my first view to work but my second one doesn't write out the correct URL to go to the third one. So, for example, I want my URLs to be:
/animals/
/animals/canines/
/animals/canines/schnauzer
I have the default route setup:
> routes.MapRoute( _
> "Default", _
> "{controller}/{action}/{id}", _
> New With {.controller = "Home", .action = "Index", .id =
> UrlParameter.Optional} _
> )
The first URL works great and I can list the animal groups on the first one along with the correct links to the second URLs. I do that as follows:
for each animal in model
Html.ActionLink(animal.animal_name,animal.animal_name.Trim)
next
I also can get the canine groups written out on the second (so I know my model is working), however the URL.Action on that second "canines" page loses the "canines" in the URL so it renders as:
/animals/schnauzer
I've tried every way I can think of to write out the link including:
<a href="<%= url.action(canine.dog_name.Trim)) %>">
<a href="<%= Url.Content("~" & url.action(canine.dog_name.Trim)) %>">
and a few others that aren't worth showing. ;-D
... I'm guessing I'm missing something in a route path but what is it? It can't be that I have to know the path I'm at on every page in order to write out the URL - can it?
Thanks in advance for your help!
The route youve configured looks for three components, a controller, action and id.
In your case /animals/schnauzer, you're looking for more than a single route element as far as HTTP routing (and link generation), is concerned. It sees /animals/canines as two different values.
If you're looking to allow a route like http://yoursite/Family/Species, specify it as such:
routes.mapRoute("familyspecies", "animals/{family}/{species}", new { controller = "Home", action = "Animals", Species = UrlParameter.Optional});
and pass family and species in to your actions
public ActionResult Animals(string family, string species){...}
OR
Use wildcard routes to direct everything after the action to the id
routes.MapRoute("{controller}/{action}/{*id}");

Running ASP.NET MVC in a subdomain makes Html.ActionLink render broken links

I am running MVC in a subdomain
http://test.domain.com which points to the /Test directory on my webhost4life account.
Html.ActionLink("About", "About", "Home")
it renders a link to
http://test.domain.com/Test/Home/About -- which gives a 404
the link should be ..
http://test.domain.com/Home/About
is there a way to override ActionLink to omit the /Test on render?
Thank you
Experiment 1
I added a route to the table like this...
routes.MapRoute(
"Test", // Route name
"Test/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
and now action link renders links like this..
http://test.domain.com/Test/Test/Home/About/
when this is clicked it does not give a 404 but gives the Home controler About action.
Result
No more broken links but the site renders ugly urls.
For a site using lots of subdomains I use a nifty MVC extension from ITCloud called UrlRouteAttribute. It allows you to assign a route to every action as an attribute setting the path and name. I have extended this to allow fully qualified paths - so to include the domain/subdomain the controller should attach to. If this is something you'd be interested in I'll upload a copy somewhere.

I'm getting a "Does not implement IController" error on images and robots.txt in MVC2

I'm getting a strange error on my webserver for seemingly every file but the .aspx files.
Here is an example. Just replace '/robots.txt' with any .jpg name or .gif or whatever and you'll get the idea:
The controller for path '/robots.txt'
was not found or does not implement
IController.
I'm sure it's something to do with how I've setup routing but I'm not sure what exactly I need to do about it.
Also, this is a mixed MVC and WebForms site, if that makes a difference.
You can ignore robots.txt and all the aspx pages in your routing.
routes.IgnoreRoute("{*allaspx}", new {allaspx=#".*\.aspx(/.*)?"});
routes.IgnoreRoute("{*robotstxt}", new {robotstxt=#"(.*/)?robots.txt(/.*)?"});
You might want to ignore the favicon too.
routes.IgnoreRoute("{*favicon}", new {favicon=#"(.*/)?favicon.ico(/.*)?"});
You can adjust the regular expression to exclude paths.
Haacked from the source.
The ignore route given above didn't work for me but I found a similar one that did:
routes.IgnoreRoute("{*staticfile}", new { staticfile = #".*\.(css|js|gif|jpg)(/.*)?" });
This error could also happen if inside a view in your area, you use the Html.Action helper. This helper will always use the area as a prepend, unless you specifically tell it not to. E.g.,
#Html.Action("Main", "Navigation", new { area = string.Empty })
I found another solution too... While I don't think I'll use it, it's worth showing here in the answers:
The following should (in theory) ignore looking for controllers for anything with a '.' in it.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }, // Parameter defaults
new { controller = #"[^\.]*" } // Parameter contraints.
);
Do you still have:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
... in your Global.asax.cs?
MVC puts it there by default, and it's supposed to handle this.
If you do, then the problem may be how you're mixing MVC and WebForms.
I encountered this error when I request resources that did not exist.
Specifically, I was requesting a custom IE css file:
<!--[if lt IE 8]>#Styles.Render("~/Content/ie7.css")<![endif]-->
(These are condition comments, interpreted by IE)
However, the actual resource existed on ~/Content/ie/ie7.css.
So, without any modifications to the routing, the error was solved by using the correct url of the resource.

Resources