How do I change the route of an ASP.NET MVC controller? - c#

I have a typical ASP.NET MVC controller, but I just want to change its route. The default route now is:
Blog/{controller}/{action}/{id}
I want to change the route of a specific controller to
Blog/Admin/{controller}/{action}/{id}"
I tried to achieve this by adding the Route, RouteArea and RoutePrefix attributes to the controller but without any success.
How can I achieve this?

Add this route prior to the default
routes.MapRoute(
name: "BlogAdmin",
url: "Blog/Admin/{action}/{id}",
defaults: new { controller = "YourSpecificControllerName", action = "Index or other default action name", id= UrlParameter.Optional });
Since this is for a specific you don't need {controller} part in your url. If you still want to specify it change the url argument to "Blog/Admin/YourSpecificControllerName/{action}/{id}" where YourSpecificControllerName is the name of your controller.
Also since the order of rote registration matters make sure that this route registered prior to the the default one

Related

MVC Attribute Routing RoutePrefix does not work with default routing

I have a work-around, but I'd really like to know why this doesn't appear to work in MVC. (.Net 4.6.1)
I have a controller which I want to use a RoutePrefix:
[RoutePrefix("entry")]
public class DefaultController : Controller
{
[HttpGet]
[Route(), Route("Index")]
public ActionResult Index()
{
// ...
}
}
In the route config:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "entry", action = "index", id = UrlParameter.Optional }
The issue is that with this configuration, running under local IIS to test, navigating to "localhost/testApp/entry" works, "localhost/testApp/entry/index" works, however the default "localhost/testApp/" results in a 404.
This has been doing my head in because on a fresh project with the default controllers and a default set to "home" and "index" the "localhost/testApp" would render Home/Index without an issue.
I narrowed it down to the RoutePrefix being the issue. If I remove the RoutePrefix and change the defaults to: new { controller = "default", action = "index", id = UrlParameter.Optional }
Then "localhost/testApp" works, but obviously this requires using /default for other routes rather than /entry.
Also, if I leave the prefix in (switching the default controller back to "entry") and add Route("~/") to the Index method, then "localhost/testApp" also works as according to the doco that a ~ route overrides the route prefix.
I'd like to know if there is an explanation why RoutePrefix doesn't seem to play nice with default routing? I'm fine with adding a ~/ route for that default action, but it seems I'm missing some understanding on how RoutePrefix is intended to be used.
Action attribute routing has the highest priority. If you use it only route attributes will be working, everything else will be ignored. You can to one action as many routes as you need.
Since you have 2 variants - Route() and Route("Index") it works only for 2 urls -"localhost/testApp/entry" and "localhost/testApp/entry/index".
if you remove Route() it will work only for one url-lcalhost/testApp/entry/index".
If you add 3rd Route("~/") it will work for 3rd url "localhost/testApp"
Sign ~ means that any prefixes should be ignored, it starts from root.
So you can not use default conventional routing on Index action since it is only obeys routing attributes.
Also, you have a controller [RoutePrefix("entry")] attribute routing too and it that next highest priority and because of this it overrides your convention routing in the config file. This is why default routing doesn't work for this controller and it doesn't go to Index automaticaly. To make default route work you need to remove route prefix and fix web config
defaults: new { controller = "default", action = "index", id = UrlParameter.Optional }
Current default controller = "entry" doesn't exist at all.
So you have two choices to have Index as default route action - remove all attribute routing and lost all another extra routes or add one more.
Thanks to Serge for helping point out a bad assumption I had about [RoutePrefix]. The problem here turns out that [RoutePrefix] is not a substitute name for a controller, (though that is how it behaves on the surface) but rather a prefix to each individual action. While the mapping in the URL will be identical:
Example 1:
public class EntryController
{
public ActionResult Index() { ... }
}
Example 2:
[RoutePrefix("Entry")]
public class DefaultController
{
[Route("Index")]
public ActionResult Index() { ... }
}
Both of these examples would resolve "localhost/testApp/entry/index", however only the first mapping would be considered as a match for {controller}/{action} and resolve a "defaults" mapping of "entry/index".
So if an action /w Attribute-based routing needs to be made a root default you need to explicitly declare it as the root using [Route()] if there is no [RoutePrefix], or [Route("~/")] if there is a [RoutePrefix]. since it won't be included in the {controller}/{action} routing. (Verified by removing the Default {controller}/{action} routing entirely).

MVC routing - specify id without action

I would like to specify an id without having to include the index action.
Here is what I have tried:
routes.MapRoute("Upload", "Upload/{id}",new { controller = "Upload", action = "Index" });
This gives a 404 error. The url will be something like site.com/Upload/123
Probably you need to put the code before the Default route. MVC check routes from the any route after default won't work

How can I route requests to a page controller for routes that don't exists in ASP.NET MVC 4

How can I route requests to a default PageController for routes that do not map to a controller or action? But for routes that do match a controller or action, have those behave as normal, using ASP.NET MVC?
Basically I have a CMS backend that I have developed and I need to be able to inspect the route, to see if it matches a route for a page, stored in the database and if so, forward the request to the default PageController, which handles loading the pages content from the database. There are also CORE pages, that do have their own Controllers and Actions defined, and if you enter a route that doesn't match a pages route in the database, I need it to revert to the default behavior of ASP.NET MVC and look for the {controller}/{action}.
I have searched and searched online, with not much luck finding how I could do this. Any help would be greatly appreciated.
Set your routes up so the ones for existing controllers and actions are first, then have a catchall that maps to your PageController:
// More specific routes go here
routes.MapRoute(
null,
"{controller}/{action}/{id}", // URL with parameters
new { action = "Index", id = UrlParameter.Optional }, // Don't put a default for controller here
// You need to constrain this rule to all of your controllers, so replace "ControllerA" with an actual controller name, etc
new { controller = "ControllerA|ControllerB|ControllerC" }
);
routes.MapRoute(
null,
"{*path}",
new { controller = "Page", action = "Index" }
);
Anything that isn't matched by the first rule and any rules you put before it will fall back to your page controller, with the path in a path parameter on your index action method.

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

URL routing in asp.net mvc

i have a ApplicationController class with an action called Admin
so my url is www.mysite.com/Application/Admin
is there anyway i can have the routing be www.mysite.com/Admin and go to this method.
i know i can do this by creating an AdminController but for this one function i thought it was easier to just put in another controller
Put this above your default route:
routes.MapRoute(
"ShortRoute",
"{action}",
new { controller = "Application", action = "Index"}
);
You can set the Application controller and the Admin method as the default controller and action, using parameter defaults:
routes.MapRoute(
"Default", // Route name
"{action}", // URL with parameters
new { controller = "Application", action = "Admin" }
);
If this is your last route, it will match any request that does not have a controller name and an action name in it. In this particular example, even a request without an action will execute your Admin action, since it's the default action.
Note that routes with parameter defaults can create strange behavior in your existing routes, if you have any. You can always use the ASP.NET MVC Routing Debugger to test which routes match a given URL.

Categories

Resources