By default for URL routing in MVC is {controller}/{action}/{id}. Then we can access mydomain.com/Products/Details/1 and etc.
Now, I have register another map route I called CategoryLandingPage.
routes.MapRoute(
name: "CategoryLandingPage",
url: "category",
defaults: new { controller = "Category", action = "Index" });
So it will show all the category in the page.
Then I register another map route called CategoryDetails
routes.MapRoute(
name: "CategoryDetails",
url: "category/{categoryName}",
defaults: new { controller = "Category", action = "Details", categoryName = UrlParameter.Optional });
When somebody access mydomain.com/category/cars, it will show all the products with related to the cars.
Same controller also have another actions such Create,Edit,Delete, and more.
The problems is,When I access mydomain.com/category/create it will go to the Details action. It not go to the create action in Category Contoller.
How can I solved this matter?
Two ways:
Either use a Route Constraint to ensure the {categoryName} part is a match for one of your categories:
//You will have to make this
var categoryRouteConstraint = new CategoryRouteConstraint();
routes.MapRoute(
name: "CategoryDetails",
url: "category/{categoryName}",
constraints: new { categoryName = categoryRouteConstraint }
defaults: new { controller = "Category", action = "Details", categoryName = UrlParameter.Optional });
Example route constraint:
public class CategoryRouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.UrlGeneration)
return true;
if (string.Equals(parameterName, "categoryName", StringComparison.OrdinalIgnoreCase))
{
//return true if (string)values[parameterName] == "known category name"
}
return false;
}
}
Or, intercept the specific actions first:
routes.MapRoute(
name: "CategoryDetails",
url: "category/create",
defaults: new { controller = "Category", action = "Create", categoryName = UrlParameter.Optional });
routes.MapRoute(
name: "CategoryDetails",
url: "category/delete",
defaults: new { controller = "Category", action = "Delete", categoryName = UrlParameter.Optional });
//Do one for Edit, Delete
//CategoryDetails route after
routes.MapRoute(
name: "CategoryDetails",
url: "category/{categoryName}",
defaults: new { controller = "Category", action = "Details", categoryName = UrlParameter.Optional });
While the answers above are correct, this is a simpler solution, although it will not dynamically update if you add actions to your controller as Dave's answer will.
As I understand it if {key} is an existing action you want it to be handled by the default route instead of using the Details action on the Category controller.
In order to achieve that you could list all the possible actions in the key constraint:
routes.MapRoute(
name: "CategoryDetails",
url: "Category/{key}",
defaults: new { controller = "Category", action = "Details" },
constraints: new { key = @"[^create|update|delete]" }
);
In this example the CategoryDetails
route will match only if the url is not Category/create
or Category/update
or Category/delete
. For example ads/cars will match and use the Details
action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With