使用slug和id的MVC url路由。使默认路由变得混乱

时间:2017-09-14 09:23:05

标签: asp.net-mvc url-routing slug

我试图让我的网址看起来很漂亮,而且很友好。我认为我已经成功但是我的默认路由停止了工作。 当我转到这个example.com/location/viewlocation/528时,网址最终会像example.com/528/a-nice-location

那太好了! 但是现在我正常的东西起作用了。 输入example.com/home/index会导致错误

  

参数字典包含参数' id'的空条目。非可空类型的System.Int32' for method' System.Web.Mvc.ActionResult ViewLocation(Int32,System.String)'在' Oplev.Controllers.LocationController'。可选参数必须是引用类型,可空类型,或者声明为可选参数。

我尝试了不同的解决方案,但我遗漏了一些东西。不能让它发挥作用。

我的代码: 的 RouteConfig

routes.MapRoute(
            name: "view_location",
            url: "{id}/{slug}",
            defaults: new { controller = "Location", action = "ViewLocation", id = UrlParameter.Optional, slug = UrlParameter.Optional }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

位置控制器

public ActionResult ViewLocation(int id, string slug)
    {
        if (string.IsNullOrEmpty(slug))
        {
            slug = "a-nice-location"; // testing..
            return RedirectToRoute("view_location", new { id = id, slug = slug });
        }
        return View();
    }

家庭控制器

    public ActionResult Index()
{
    return View();
}

3 个答案:

答案 0 :(得分:1)

您的第一条路线会匹配网址中包含0,1或2段的所有内容。例如,它匹配../Home/Index。你需要一些方法来区分它,例如你可以做到它

routes.MapRoute(
    name: "view_location",
    url: "ViewLocation/{id}/{slug}",
    defaults: new { controller = "Location", action = "ViewLocation", slug = UrlParameter.Optional }
);

或者您可以添加路线约束

另请注意,只有最后一个参数可以标记为UrlParameter.Optional,但在您的情况下,id无论如何都不是可选的

答案 1 :(得分:0)

好的,所以我不知何故最终得到了有效的东西! 将view_location的路由更改为:

            routes.MapRoute(
            name: "view_location",
            url: "{id}/{slug}",
            defaults: new { controller = "Location", action = "ViewLocation", slug = UrlParameter.Optional},
            constraints: new { id = @"\d+" }
        );

答案 2 :(得分:0)

这是为了补充已经给出的答案。具有路径约束的属性路由也将起作用。

首先确保在RouteConfig

中启用了属性路由
//Attribute routing
routes.MapMvcAttributeRoutes(); // placed before convention-based routes

//convention-based routes
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

接下来在控制器上使用必要的Route属性

[HttpGet]
[Route("{id:int}/{*slug?}", Name = "view_location")] // Matches GET 528/some-nice-location
public ActionResult ViewLocation(int id, string slug) {
    if (string.IsNullOrEmpty(slug)) {
        slug = "a-nice-location"; // testing..
        return RedirectToRoute("view_location", new { id = id, slug = slug });
    }
    return View();
}