MVC routes with different actions when path has similar pattern - asp.net-mvc

In my MVC app I have two paths with a similar pattern and my route config file has methods like below.
routes.MapRoute(
name: "Route1",
url: "bookings/{username}",
defaults: new { controller = "Booking", action = "UserBooknigs" }
);
routes.MapRoute(
name: "Ruote2",
url: "bookings/{username}/{id}",
defaults: new { controller = "Booking", action = "LoadBooking" }
);
whichever path I access it calls both actions. How can I avoid this issue?

Related

ASP.NET MVC4 - Different routing for 2 controllers with actionLinks

Okay, I've got this case where I have two controllers:
HomeController
MathController
I want the routing for my HomeController to stay as default:{controller}/{action}/{id}. But I want to access the actions in the MathController with http://myurl/Task/Math/{action}.
So what I've done is to write my RouteConfig like this:
routes.MapRoute(
name: "Math",
url: "Task/{controller}/{action}",
defaults: new { controller = "Math", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Hem", id = UrlParameter.Optional }
);
When using the above configuration and manually entering the URLs in the browser both routing methods are working. Though when trying to add a "actionLink" it always uses the Task/{Controller}/{Action} route. Even if I'm creating a link for the Home controller like this: #Html.ActionLink("Hem", "Hem", "Home", null, new { #class = "navbar-brand" })
How do I configure either my routing or my action links so that I'll get the preferred functionality?
Routes match from top down in RouteConfig.cs. Your problem is that both route configs are "catch all" routes, which means both work for any controller/action. When you use #Html.ActionLink, MVC will render the url based on the 1st route it finds, which matches your "Task" path. There are few ways to change this to get what you want.
If you want to only use the "Task" path for the Math controller, then I'd change your route to this:
routes.MapRoute(
name: "Math",
url: "Task/Math/{action}",
defaults: new { controller = "Math", action = "Index" }
);
If you want to use several controllers for the "Task" path, then you can add a route constraint. You can use it like below and specify a list of controllers (regex), or you can create your own custom Route Constraint class and implement whatever functionality you want.
routes.MapRoute(
name: "Math",
url: "Task/{controller}/{action}",
defaults: new { controller = "Math", action = "Index" },
constraints: new { controller = "Math|OtherController" }
);
Or if you want to keep all controllers/actions matching both urls, then you have to flip your routes to get the default route to display first, or you can use #Html.RouteLink like so:
#Html.RouteLink("Hem", "Default", new { controller = "Home", action = "Hem" }, new { #class = "navbar-brand" })

Change Index of Directory

I'm working on an ASP.NET MVC web application. By default, browsing to the root of a directory seems to call the controller's Index() method. Is there way to change which method is called by default here? I know I could probably name the method I want to call "Index" and it would likely work, but I'd like to know if there's a way to point the directory root to a method that I choose.
For example: mysite.com/MyDirectory/ will call Index(), which is effectively browsing to mysite.com/MyDirectory/Index. I'd like to change it so that mysite.com/MyDirectory/ calls Details, (or "browses" to mysite.com/MyDirectory/Details).
Just change the action in the default route. Something like this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Details", id = UrlParameter.Optional } // Parameter defaults
);
You could specify the behavior in your routes. If you are using the latest version of MVC, that would be in your \App_Start\RouteConfig.cs
You would have something like:
routes.MapRoute(
name: "MyDirectory",
url: "MyDirectory",
defaults: new { controller = "MyDirectory", action = "Details" });
You would place this before your default route, as your route table acts kind of like a switch statement matching on the first route that it finds.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "MyDirectory",
url: "MyDirectory",
defaults: new { controller = "MyDirectory", action = "Details" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

Aspnet MVC 4 routing challenges

I want customized routing based on Department Name and Product Name. for example /mobiles/nokia-6303
when i am calling products page it's working fine. when i am calling other than product page like Home page by default following controller and action method is executing
defaults: new { controller = "ContentPage", action = "ProductDetail" }
how to avoid this problem?
routes.MapRoute(
name: "ProductDetailsPage",
url: "/{DepartmentName}/{ProductName}",
defaults: new { controller = "ContentPage", action = "ProductDetail" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
Thanks in advance
Rajesh
Your routes are exactly the same. It's impossible to differentiate between /DepartmentName/ProductName and /Controller/Action. You need something else in the URL in order to differentiate between the two things, e.g.:
routes.MapRoute(
name: "ProductDetailsPage",
url: "/Products/{DepartmentName}/{ProductName}",
defaults: new { controller = "ContentPage", action = "ProductDetail" }
);
And then navigate to /products/departmentname/productname
Perhaps a slight modification to Ant P's excellent suggestion would be to place the text in between department name and product name?
routes.MapRoute(
name: "ProductDetailsPage",
url: "/{DepartmentName}/Products/{ProductName}",
defaults: new { controller = "ContentPage", action = "ProductDetail" }
);
Or to have details afterwards:
routes.MapRoute(
name: "ProductDetailsPage",
url: "/{DepartmentName}/{ProductName}/details",
defaults: new { controller = "ContentPage", action = "ProductDetail" }
);
Either of these URL approaches might get past your 'SEO team', since it is including soemwhat relevant information within the URL.
As other answers mention, the routing system can't differentiate between {controller}/{action} and {DepartmentName}/{ProductName}.
You can solve this problem by adding a constraint to a route. If a constraint isn't fulfilled, the route won't match the URL. You will probably need to create a custom implementation of IRouteConstraint. I see two options:
Create a constraint for the {controller}/{action} route, that will contain a list of possible names of controllers, that should be use the default URL pattern
Create a constraint for the {DepartmentName}/{ProductName} route, that will check the database (or some in-memory cache) whether department name and product name match some product
finally i have fixed this issue using routing config itself, please find the below code.
foreach (var d in departmentTranslation)
{
routes.MapRoute(
"ContentPage" + d.Name,
d.Name + "/{ProductName}",
new
{
controller = "ContentPage",
action = "ProductDetails",
id = d.DepartmentId,
ProductName = UrlParameter.Optional
});
}

Routing with and without controller name in ASP.NET MVC 4

I'm using ASP.NET MVC 4 and I have some problems settings up my routes. Could you tell my how to set up my routes to point urls to actions as follows:
"/" (or "/Start") => PublicController.Start()
"/About" => PublicController.About()
"/MyPage" (or "/MyPage/Summary") => MyPageController.Summary()
"/MyPage/Invoices" => MyPageController.Invoices()
"/MyPage/Invoice/72" => MyPageController.Invoice(int id)
It's the url "/About" that messes things up for me, i.e. a url that does not specify the controller. If I make that one work the others that do specify controller stop working. I could just create a separate controller for "/About" I guess, but I'd rather not if I don't have to (I have more urls following that pattern).
This should do it:
routes.MapRoute(
name: "About",
url: "About",
defaults: new { controller = "Public", action = "About" }
);
routes.MapRoute(
name: "MyPageSummary",
url: "MyPage",
defaults: new { controller = "MyPage", action = "Summary" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Public", action = "Start", id = UrlParameter.Optional }
);

ASP.NET MVC long Route issue

How I can to avoid route config like that?
I have an admin panel where user with administrator role is able to do some action(edit/delete/view) with different entities(users/profiles/addresses/...).
And i want put all this action into 1 controller.
routes.MapRoute(
name: "EditProfile",
url: "Account/Profiles/{id}/Edit",
defaults: new { controller = "Account", action = "EditProfile" }
);
routes.MapRoute(
name: "RemoveProfile",
url: "Account/Profiles/{id}/Remove",
defaults: new { controller = "Account", action = "RemoveProfile" }
);
routes.MapRoute(
name: "EditAddress",
url: "Account/Addresses/{id}/Edit",
defaults: new { controller = "Account", action = "EditAddress" }
);
routes.MapRoute(
name: "RemoveAddress",
url: "Account/Addresses/{id}/Remove",
defaults: new { controller = "Account", action = "RemoveAddress" }
);
//...
Basically I want replace all MapRoute to smth like this:
routes.MapRoute(
name: "AccountProfileActions",
url: "Account/{entities}/{id}/{subAction}",
defaults: new { controller = "Account", action = {subAction} + {entities}}
);
How can I do this?
Just don't specify the action (or controller for that matter) and rely on MVC Route conventions, i.e. the controller name and action name will be part of the URL.
If you want to have a specific route that does not match up with your controller/action names, then consider using something like AttributeRouting, which will let you specify the route right on your controller/action, instead of having to go into RouteConfig each time.

Resources