MVC 区域和 HTML Slug

MVC Areas and HTML Slug

我正在尝试缩短我的 MVC 应用程序上的 URLs(如果可能的话)。我在我的网络应用程序上使用区域。目前我有 URL slugs 工作,这个 seite 帮助很大:http://www.itorian.com/2016/12/slug-url-in-mvc.html

这是我的工作区域注册的一部分,请注意 {articleTitle} 是 slug。

public override void RegisterArea(AreaRegistrationContext context)
        {       
            context.MapRoute(
                "Discussion_default",
                "Discussion/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );

            context.MapRoute(
                "View_Article",
                "Discussion/Articlev1/Details/{id}/{articleTitle}",
                new { controller = "Articlev1", action = "Details", id = UrlParameter.Optional, articleTitle = "" }
            );
        }

这会生成一个长 URL (www.sitename.com/Discussion/Articlev1/Details/id/cool-html-article)

有没有办法让它生成并使用类似的东西:

www.sitename.com/Articlev1/id/cool-html-article

甚至只是让它像这样省略细节部分:

www.sitename.com/Discussion/Articlev1/id/cool-html-article

我已经尝试了一些方法,但其中 none 有效,生成 404 错误或 400.1 错误。这可能吗?

根据您设置路由的方式,View_Article 路由永远不会被命中,除非您生成 URL,因为 URL /Discussion/Articlev1/Details/id/cool-html-article 将匹配 Discussion_default路线。

首先,把它们按正确的顺序排列():

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "View_Article",
        "Discussion/Articlev1/Details/{id}/{articleTitle}",
        new { controller = "Articlev1", action = "Details", id = UrlParameter.Optional, articleTitle = UrlParameter.Optional }
    );

    context.MapRoute(
        "Discussion_default",
        "Discussion/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}

从那里开始,很容易将第一个 URL 更改为您喜欢的任何内容,只要您注意确保整个配置中没有 URL 冲突。

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "View_Article",
        "Discussion/Articlev1/{id}/{articleTitle}",
        new { controller = "Articlev1", action = "Details", id = UrlParameter.Optional, articleTitle = UrlParameter.Optional }
    );

    context.MapRoute(
        "Discussion_default",
        "Discussion/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}

NOTE: It also probably doesn't make sense to have a View_Article URL that doesn't have an id, so you shouldn't make id = UrlParameter.Optional in that case.

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "View_Article",
        "Discussion/Articlev1/{id}/{articleTitle}",
        new { controller = "Articlev1", action = "Details", articleTitle = UrlParameter.Optional }
    );

    context.MapRoute(
        "Discussion_default",
        "Discussion/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}

当然,这意味着如果你的应用程序中有一个名为ArticleV1Controller的控制器,View_Article路由将匹配(并将id参数设置为你传递的操作在 URL) 中。如果您无法忍受将 /Details 段硬编码到 URL 中,那么您将需要以其他方式区分它,例如使用路由约束。以下假定您的 ID 必须是全数字:

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        name: "View_Article",
        url: "Discussion/Articlev1/{id}/{articleTitle}",
        defaults: new { controller = "Articlev1", action = "Details", articleTitle = UrlParameter.Optional },
        constraints: new { id = @"\d+" }
    );

    context.MapRoute(
        name: "Discussion_default",
        url: "Discussion/{controller}/{action}/{id}",
        defaults: new { action = "Index", id = UrlParameter.Optional }
    );
}