如何创建 URL 友好路由并删除索引

How to Create URL friendly route and remove index

我知道如何创建 URL 友好路线,我也知道如何删除索引。但我想知道如何将两者结合起来?

使用本教程 https://www.jerriepelser.com/blog/generate-seo-friendly-urls-aspnet-mvc/ 我能够添加以下代码以允许 url 友好路由。

routes.Add("ProductDetails", new SeoFriendlyRoute("drink/{id}",
    new RouteValueDictionary(new { controller = "Drink", action = "Index" }),
    new MvcRouteHandler()));

所以我的 url 现在变成了 test.com/index/drink/coke

而不是 test.com/index/drink/1

我的下一组代码是从 url 中删除索引。

routes.MapRoute("DrinkRoute",
    "drink/{id}",
    new { controller = "Drink", action = "Index" });

这将成功地将 test.com/index/drink/1 转换为 test.com/drink/1

请问如何将两者结合起来,以便我可以有一条路线引导我进行正确的控制器操作并显示 test.com/drink/coke

路由配置

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

如果我理解正确,你可以通过 RouteConfig.cs:

实现所需的行为
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "DrinkRoute",
            url: "drink/{id}",
            defaults: new { controller = "Drink", action = "Index" }
        );

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

在那种情况下,url test.com/drink/coke 将被控制器 DrinkController.cs 和操作方法 Index 击中。 ID 将为 coke。该控制器的源代码:

public class DrinkController : Controller
{
    public ActionResult Index(string id)
    {
        return View();
    }
}

您也可以使用属性路由实现相同的目的,这将提供对所需路由的更多控制。

引用Attribute Routing in ASP.NET MVC 5

首先,您需要通过在 RouteConfig 中调用 routes.MapMvcAttributeRoutes(); 来启用属性路由。确保它在基于约定的路由之前注册。

public class RouteConfig {
    public static void RegisterRoutes(RouteCollection routes) {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        //Attribute routes
        routes.MapMvcAttributeRoutes();

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

启用属性路由后,您可以通过注释操作和控制器来指定路由。

[RoutePrefix("drink")]
public class DrinkController : Controller {
    [HttpGet]
    [Route("{name}")] // GET drink/coke
    public ActionResult Index(string name) {

        //...use name to get model

        return View();
    }

    //..
}

上面的 DrinkController.Index 操作现在映射到 GET drink/coke 假设 test.com 是控制器的主机,如您的示例所示。

任何未被路由属性注释的控制器或动作将默认回到在路由 table.

中注册的基于约定的路由(如果有的话)

这意味着您可以为控制器混合定义基于约定和基于属性的路由。

但是请注意,一旦您在控制器上使用属性路由,您就必须在其所有 public 操作中使用它。

您可以删除 SEO 路由并赋予您的操作或控制器完全控制权:

public class DrinkssController : Controller
{
    [Route("drink/{drinkName}")]
    public ActionResult Index(string drinkName)
    {
        var model = _drinks.First(x => x.name == drinkName);
        return View(model);
    }
}