Routing Invalid Access to Action

By default, MVC uses {controller} / {action} / {id} for URL routing. Then we can access mydomain.com/Products/Details/1, etc.

Now I have another map route, which I called CategoryLandingPage .

routes.MapRoute( name: "CategoryLandingPage", url: "category", defaults: new { controller = "Category", action = "Index" }); 

Thus, it will show the entire category on 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 someone gets access to mydomain.com/category/cars , he will show all the products related to cars.

The same controller also has other actions, such as Create, Edit, Delete, and more .

Problems: when I turn to mydomain.com/category/create , it will go to the action Details . It does not go to the create action in the Contoller category.

How can I solve this problem?

+5
source share
3 answers

Two ways:

Use Route Restriction to ensure that the {categoryName} part matches 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 restriction:

 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 first intercept specific actions:

 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 }); 
+4
source

While the answers above are correct, this is a simpler solution, although it will not be dynamically updated if you add actions to the controller, like Dave's answer.

As I understand it, if {key} is an existing action that you want it to be handled by the default route, instead of using the Details action on the category controller.

To achieve this, you can list all the possible actions in a 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 only match if the URL is not Category/create or Category/update or Category/delete . For example, ads / cars will match and use the Details action.

+2
source

You cannot do that. You rejected the default route at the URL: "category / {categoryName}"

A good way to solve the routing problem is to name it as shown below:

  • items / - for a list of items
  • items / {name_or_id} / details - to show item details
  • items / {name_or_id} / edit - to update an item
  • items / create - tu create a new item

In your case, it could be:

  routes.MapRoute( name: "CategoryLandingPage", url: "categories", defaults: new { controller = "Category", action = "Index" }); routes.MapRoute( name: "CategoryDetails", url: "categories/{categoryName}/details", defaults: new { controller = "Category", action = "Details" }); routes.MapRoute( name: "CategoryUpdate", url: "categories/{categoryName}/edit", defaults: new { controller = "Category", action = "Edit" }); routes.MapRoute( name: "CategoryLandingPage", url: "categories/create", defaults: new { controller = "Category", action = "Create" }); 
0
source

All Articles