路由错误访问动作

本文关键字:访问 错误 路由 | 更新日期: 2023-09-27 18:02:51

MVC中的URL路由默认为{controller}/{action}/{id}。然后我们可以访问mydomain.com/Products/Details/1等。

现在,我已经注册了另一个地图路由,我叫CategoryLandingPage

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

因此它将显示页面中的所有类别。

然后注册另一个名为CategoryDetails的map路由

routes.MapRoute(
name: "CategoryDetails", 
url: "category/{categoryName}", 
defaults: new { controller = "Category", action = "Details", categoryName = UrlParameter.Optional });

当有人访问mydomain.com/category/cars时,它将显示与汽车相关的所有产品。

同一控制器还具有其他操作,如创建,编辑,删除和更多

问题是,当我访问mydomain.com/category/create时,它将转到Details操作。它不会转到类别控制器中的创建操作。

我该如何解决这个问题?

路由错误访问动作

两种方式:

使用路由约束来确保{categoryName}部分与你的一个类别匹配:

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

路由约束示例:

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

或者,先截取特定的动作:

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

虽然上面的答案是正确的,但这是一个更简单的解决方案,尽管它不会像Dave的答案那样在控制器中添加操作而动态更新。

据我所知,如果{key}是一个现有的操作,你希望它由默认路由处理,而不是使用类别控制器上的Details操作。

为了实现这一点,您可以在键约束中列出所有可能的操作:

routes.MapRoute(
    name: "CategoryDetails",
    url: "Category/{key}",
    defaults: new { controller = "Category", action = "Details" },
    constraints: new { key = @"[^create|update|delete]" }
);

本例中,只有url不是Category/createCategory/updateCategory/delete时,CategoryDetails路由才会匹配。例如,广告/汽车将匹配并使用Details动作。

你不能这样做。你重写了url: "category/{categoryName}"的默认路由

解决路由问题的一个好方法是像这样命名它:

  • items/-用于元素列表
  • items/{name_or_id}/details -显示元素
  • 的详细信息
  • items/{name_or_id}/edit -更新
  • 元素
  • items/create -创建新元素

对于您的情况,可以是:

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