MVC Areas and routing issue - c#

I'm having some issues getting Areas working correctly within MVC 3. I have the following folder structure and an Admin area set up:
I'm trying to navigate from the admin page (Index) to the the other view pages in the Admin area for example Admin/Floor/Create etc... but I get The resource cannot be found error on every url combination i've tried for example:
#Html.ActionLink("floors", "Index", "Floor", new { area = "Admin" }, null)
/Floor/Index/
/Admin/Floor/Index/
None of which work. I managed to use the first ActionLink one to link to the admin index page from outside of the area but it's no use here.
The area registration looks like this:
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
Can anyone offer some help?
Thankyou

The problem is with your routing. You need to set the default controller to be AdminController:
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller = "Admin", action = "Index", id = UrlParameter.Optional }
);
If you don't specify this, MVC doesn't know quite what you're looking for and actually expects you to navigate to /admin/admin in order to display the initial view. So change the routing as I've mentioned above and then use this action link to get to FloorController.Create():
#Html.ActionLink("floors", "create", "floor", new { area = "admin" }, null)
To expand a little, with your routing setup this way, your URLs will look like this:
/admin // Executes AdminController.Index()
/admin/floor // Executes FloorController.Index()
Update
Having downloaded Maciej Rogoziński's project, this gives me the same problem that your project currently has. The link from the default action is linking to /admin/admin/, which as I mentioned earlier, is what your project is looking for because no default controller has been specified for the area routing (this also applies to Maciej's project). Specifying the default controller allows you to navigate to /admin, which results in AdminController.Index() being invoked. Without specifying that controller, you can only retrieve this view from routing to /admin/admin, which again, is what Maciej's application is doing.

Related

MVC 4 - issue with routing to non-area controllers

I have a project that I am upgrading from MVC 2 -> MVC 4. During the transition from MVC 2 -> MVC 3, I noticed that some of my hyperlinks broke and were no longer matching the routes as defined before. I have the following project structure:
...
App_Data
Areas
Test
Controllers
TestController
Views
Models
Controllers
PartialController
Views
Scripts
...
The links that are generated are in the format /Test/Partial/Render. If I go back and run the project before the migration, the PartialController Render action is hit as expected. However, now the app says that it can't find an action because there is no Test/Partial controller. I actually am not sure how it worked before, but can't seem to get it to map correctly.
Is there something I'm missing? Here is the relevant code:
Global.asax.cs:
...
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
...
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = "" }
);
TestAreaRegistration.cs:
context.MapRoute(
"Test_default",
"Test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
I did move the Controllers folder up a level to be more in-line with how the project should be structured; beforehand it was in the Areas folder itself. However, none of this worked before I moved that, so I doubt that is the case. I also thought that Autofac had something to do with this, but I am less certain of that because if I shave the "Test" portion out of the URL it matches as expected.
I guess this all boils down to a question on how to check in a "generic" controllers directory first, before matching to an area-specific controller directory, even with an area specified in the URL.
Thanks in advance for your help!
EDIT: If it helps, I noticed that in the existing MVC 2 solution, if I go to Test/Home for example, it will invoke the Index method of the HomeController. However, this does not happen in the new solution. Is this because there is no View associated with the new routes? I have not made new .cshtml files for each of the corresponding .ascx files yet, but I didn't think that should matter much as they are used otherwise.
So apparently the issue was related to namespaces. I had seen that answer on questions like this, but those had to do with collisions finding views. Here is the line I ended up adding to each of my Area registrations:
context.MapRoute(
"Test_default",
"Test/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "Project.Web.Controllers", "Project.Web.Areas.Test.Controllers" } //added this line
);

Setting Help Page as default route

I have a C# .Net 4.5 Web Api application to which I have added a Help Page such as the one shown here.
When a developer launches the Web Api application in Visual Studio, I would like the help page to come up.
I would like to accomplish this by the using routing (such as a change to WebApiConfig.cs or Global.asax.cs) as opposed to a setting in the project's properties.
In the WebApiConfig.cs file I tried adding the following -
config.Routes.MapHttpRoute("Default", "api/help");
That did not work. Does anyone know how to make this work? Thanks.
Two years late, but for the benefit of Googlers like myself - A way to do it (based on this answer) is simply to modify the RegisterArea method in the HelpPageAreaRegistration.cs class in the HelpPage Area to contain a blank route. Example -
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"HelpPage_Default",
"Help/{action}/{apiId}",
new { controller = "Help", action = "Index", apiId = UrlParameter.Optional });
context.MapRoute(
"Help Area",
"",
new { controller = "Help", action = "Index" });
HelpPageConfig.Register(GlobalConfiguration.Configuration);
}

MVC3 Routing strange behavior

I found something strange with routing...
I´m testing a MVC3 application in Visual Studio Web Express 2012
I created a new MVC3 application to isolate the problem
I added the following route before the default route:
routes.MapRoute(
"default_localization",
"{language}/{country}/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Then without any other change (there are no areas anything just the initial files after creating the project), I ran the application and at first sight everything was working fine. Since it is a new application there are two links at the top of the page:
Home
About
The action links look like:
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
Then this is what is happening:
When the browser URL is: http://localhost:54870/
The Home link is: http://localhost:54870/
The About link is: http://localhost:54870/Home/About
HTML
<li>Home</li>
<li>About</li>
Which is OK
But after clicking the About link, the browser URL is: http://localhost:54870/Home/About
The Home link becomes: http://localhost:54870/Home/About
The about link becomes: http://localhost:54870/Home/About/Home/About
They still execute the correct action even when the link is messed up.
HTML
<li>Home</li>
<li>About</li>
If I remove my custom routing everything works as expected
Why is this happening?
How can I fix it?
I just found the problem
Basically I read several routing articles and finally I got it, my problem was that my custom route was been picked up always after I clicked the About link
Why?
Let's consider it:
When my URL was http://localhost:54870/, my custom route was not picked up because I didn't have default values for {language} and {country} therefore my route didn't match
But when my URL was http://localhost:54870/Home/About my custom route was always picked up because the route engine assumed that Home/About were the {language} and {country} segments and since I had default values for {controller} and {action} the rout simply was a match
Well I learnt my lesson and I learnt more about routing. In the future I'm planning to follow the KISS principle when defining routes
Try replacing your route with something like this:
routes.MapRoute(
"default_localization",
"{language}/{country}/{controller}/{action}/{id}",
new { language = "en", country = "US", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
See if that works.
Hope this is of help to you.

Is there a way to make the route mapping based on specific path

I code lots of ASP.NET but I'm kind of new with .net MVC, I've a default route registered like this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
And I want to add another Administrator area on the site and all the URL would be something like "http://localhost/Administrator/controller1", "http://localhost/Administrator/controller2", etc. I've lot of controllers in the Administrator namespace and I'm trying to register those controller with only one MapRoute, I did something like this:
routes.MapRoute("Administrator_default", "Administrator/{controller}/{action}/{id}", new { controller = "Administrator", action = "Index", id = "" });
it works with those controller but one problem is that in some other controller while I try to do a redirect like:
return RedirectToAction("Index", "Forum");
Then I'll always be redirect to http://localhost/Administrator/Forum instead of http://localhost/Forum, it's not a big issue but make the URL looks strange, I tried to restrict to certain namespace but it's not working. It looks just as I'm trying to register two default route and .Net just match the first one, I'm wondering is there a way to make it two default route and map on only specific path only?
This exact issue is why Areas were added to MVC 2. http://www.asp.net/whitepapers/what-is-new-in-aspnet-mvc#_TOC3_2
Agree with Zach's answer.
Not ideal, but you do have the option to have controllers in the controller root folder (e.g. /controllers/HomeController.cs) of your project as well as the controllers in Areas (maybe high level root pages that display menus for areas).
Secondly a quick tip on using the RedirectToAction method. You can specify the area you would like to redirect too using the route parameters e.g:
RedirectToAction("Index","Form", new { area = "MyOtherArea" });

ASP.NET MVC Routing Strange or Unexpected Behavior

I am very new to ASP.NET MVC and am working over an eCommerce application that uses ASP.NET MVC 2.
For all the scenario, the default route works fine. But I need to define my own rule for URL like below:
http: //localhost/mvc2proj/products
http: //localhost/mvc2proj/products/productname
For this, I defined a new route just above the default routing:
routes.MapRoute(
"Products",
"Products/{productName}",
new { controller = "Products", action = "Index" }
);
It works fine when home page gets displayed. That is when the URL is http: //localhost/mvc2proj, the anchor tag's href attribute for menu header "Products" is "href="mvc2proj/Products" Products".
But when the URL is http: //localhost/mvc2proj/products/productname, the anchor tag's href attribute for menu header "Products" also gets changed to href="mvc2proj/Products/productName" which is not obviously desired. The menu href should not be changed whenever Product's category is clicked individually. It should remain unchanged.
I defined menu as a User Control like this:
<li><%=Html.RouteLink("Home", new { Controller = "Main", Action = "Index" })%></li>
<li><%=Html.RouteLink("Products", new{ Controller = "Products" } ) %></li>
Product's subcategory is defined like this:
<%foreach(var product in Model.Products) {%>
<li><%=Html.RouteLink(Html.Encode(product.ProductName), new { controller = "Products", productName = product.ProductName })%></li>
<%} %>
The HTML for subcategory is:
<li>Product1</li>
<li>Product2</li>
....... and so on. Clicking on these links changes the menu URL.
Please help me.
This may not be the best solution, but I got around a similar issue by defining a different route for the Index page than for the individual product pages, i.e. something like:
routes.MapRoute(
"ProductIndex",
"Products",
new { controller = "Products", action = "Index" }
);
This would be additional to your existing route. I think I actually used different Action methods for each, but there would be no need to if you supplied a default value for the parameter.
I am sure there is a better way and that this solution comes from a lack of understanding of what's really going on, but it may help you solve the immediate problem!

Categories

Resources