路由错误访问动作
本文关键字:访问 错误 路由 | 更新日期: 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/create
、Category/update
或Category/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" });