【问题标题】:Asp.Net MVC: How do I enable dashes in my urls?Asp.Net MVC:如何在我的网址中启用破折号?
【发布时间】:2010-09-07 00:23:09
【问题描述】:

我想在我的网址中使用破折号分隔单词。所以而不是:

/MyController/MyAction

我想要:

/My-Controller/My-Action

这可能吗?

【问题讨论】:

标签: asp.net-mvc


【解决方案1】:

您可以像这样使用 ActionName 属性:

[ActionName("My-Action")]
public ActionResult MyAction() {
    return View();
}

请注意,您需要将视图文件命名为“My-Action.cshtml”(或适当的扩展名)。您还需要在任何 Html.ActionLink 方法中引用“my-action”。

控制器没有这么简单的解决方案。

编辑:MVC5 更新

全局启用路由:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapMvcAttributeRoutes();
    // routes.MapRoute...
}

现在使用 MVC5,属性路由已被吸收到项目中。您现在可以使用:

[Route("My-Action")]

关于操作方法。

对于控制器,您可以应用 RoutePrefix 属性,该属性将应用于该控制器中的所有操作方法:

[RoutePrefix("my-controller")]

使用RoutePrefix 的好处之一是 URL 参数也可以传递给任何操作方法。

[RoutePrefix("clients/{clientId:int}")]
public class ClientsController : Controller .....

截图..

[Route("edit-client")]
public ActionResult Edit(int clientId) // will match /clients/123/edit-client

【讨论】:

  • 这是真正的答案。不知道为什么 Phil 没有添加此信息
  • 不错的提示。补充一点:当您使用默认 View() 调用执行此操作时,MVC 将在 Views 文件夹中的某处搜索“My-Action.aspx”,而不是“MyAction.aspx”,除非您明确指定原始名称。跨度>
  • @Eduardo 我认为 ActionName 属性是为预览版 5 添加的,它是在 Phil 的帖子之后发布的。
  • 如何显式指定视图文件名?我是否必须将视图文件名更改为 My-Action.aspx?
  • @LordofScripts - 确保您已正确配置路由:routes.MapMvcAttributeRoutes();
【解决方案2】:

这是我在 ASP.NET MVC 5 中使用区域所做的事情,它的工作方式非常有魅力。我也不必重命名视图。

在 RouteConfig.cs 中,执行以下操作:

 public static void RegisterRoutes(RouteCollection routes)
    {
        // add these to enable attribute routing and lowercase urls, if desired
        routes.MapMvcAttributeRoutes();
        routes.LowercaseUrls = true;

        // routes.MapRoute...
    }

在你的控制器中,在你的类定义之前添加这个:

[RouteArea("SampleArea", AreaPrefix = "sample-area")]
[Route("{action}")]
public class SampleAreaController: Controller
{
    // ...

    [Route("my-action")]
    public ViewResult MyAction()
    {
        // do something useful
    }
}

如果在本地机器上测试,浏览器中显示的 URL 是:localhost/sample-area/my-action。您不需要重命名您的视图文件或任何东西。我对最终结果非常满意。

启用路由属性后,您可以删除您拥有的任何区域注册文件,例如 SampleAreaRegistration.cs。

article 帮助我得出了这个结论。希望对你有用。

【讨论】:

    【解决方案3】:

    Asp.Net MVC 5 将支持属性路由,允许更明确地控制路由名称。示例用法如下所示:

    [RoutePrefix("dogs-and-cats")]
    public class DogsAndCatsController : Controller
    {
        [HttpGet("living-together")]
        public ViewResult LivingTogether() { ... }
    
        [HttpPost("mass-hysteria")]
        public ViewResult MassHysteria() { }
    }
    

    要为使用 v5 之前的 Asp.Net MVC 的项目获得此行为,可以使用 AttributeRouting project(也称为 available as a nuget)找到类似的功能。事实上,Microsoft 联系了 AttributeRouting 的作者,帮助他们实现 MVC 5。

    【讨论】:

    • 哇,没人提到捉鬼敢死队的参考资料吗?
    【解决方案4】:

    我为此问题开发了一个开源 NuGet 库,它隐式地将 EveryMvc/Url 转换为 every-mvc/url。

    大写 url 存在问题,因为 cookie 路径区分大小写,大多数互联网实际上是区分大小写的,而 Microsoft 技术将 url 视为不区分大小写。 (More on my blog post)

    NuGet 包:https://www.nuget.org/packages/LowercaseDashedRoute/

    要安装它,只需在 Visual Studio 中打开 NuGet 窗口,方法是右键单击项目并选择 NuGet 包管理器,然后在“在线”选项卡上键入“小写虚线”,它应该会弹出。

    或者,您可以在包管理器控制台中运行此代码:

    Install-Package LowercaseDashedRoute

    之后,您应该打开 App_Start/RouteConfig.cs 并注释掉现有的 route.MapRoute(...) 调用并添加它:

    routes.Add(new LowercaseDashedRoute("{controller}/{action}/{id}",
      new RouteValueDictionary(
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
        new DashedRouteHandler()
      )
    );
    

    就是这样。所有的 url 都是小写的、破折号的,并且无需您做任何其他操作即可隐式转换。

    开源项目网址:https://github.com/AtaS/lowercase-dashed-route

    【讨论】:

    • 在尝试了我在网上找到的十几种其他解决方案后,这是第一个真正适用于 MVC5 的解决方案。谢谢
    • 非常感谢。
    【解决方案5】:

    我对 MVC 还是很陌生,所以对它持保留态度。这不是一个优雅的、包罗万象的解决方案,但在 MVC4 中为我做了诀窍:

    routes.MapRoute(
        name: "ControllerName",
        url: "Controller-Name/{action}/{id}",
        defaults: new { controller = "ControllerName", action = "Index", id = UrlParameter.Optional }
    );
    

    【讨论】:

      【解决方案6】:

      您可以定义一个特定的路由,例如:

      routes.MapRoute(
          "TandC", // Route controllerName
          "CommonPath/{controller}/Terms-and-Conditions", // URL with parameters
          new {
              controller = "Home",
              action = "Terms_and_Conditions"
          } // Parameter defaults
      );
      

      但此路线必须在之前您的默认路线注册。

      【讨论】:

      • 类似地,使用AttributeRouting 允许您指定所需的任何路线名称,另外还有一个好处是可以准确了解您的操作与哪条路线相关联。
      【解决方案7】:

      如果您有权访问 IIS URL 重写模块 (http://blogs.iis.net/ruslany/archive/2009/04/08/10-url-rewriting-tips-and-tricks.aspx),则可以简单地重写 URL。

      对 /my-controller/my-action 的请求可以重写为 /mycontroller/myaction,然后就无需编写自定义处理程序或其他任何东西。访问者会得到漂亮的 url,而你会得到 MVC 可以理解的。

      这是一个控制器和动作的示例,但您可以将其修改为更通用的解决方案:

      <rewrite>
        <rules>
          <rule name="Dashes, damnit">
            <match url="^my-controller(.*)" />
            <action type="Rewrite" url="MyController/Index{R:1}" />
          </rule>
        </rules>
      </rewrite>
      

      这样做的可能缺点是您必须将项目切换为使用 IIS Express 或 IIS 以便在开发期间进行重写。

      【讨论】:

        【解决方案8】:

        您可以创建一个自定义路由处理程序,如本博客所示:

        http://blog.didsburydesign.com/2010/02/how-to-allow-hyphens-in-urls-using-asp-net-mvc-2/

        public class HyphenatedRouteHandler : MvcRouteHandler{
                protected override IHttpHandler  GetHttpHandler(RequestContext requestContext)
                {
                    requestContext.RouteData.Values["controller"] = requestContext.RouteData.Values["controller"].ToString().Replace("-", "_");
                    requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"].ToString().Replace("-", "_");
                    return base.GetHttpHandler(requestContext);
                }
            }
        

        ...以及新路线:

        routes.Add(
                    new Route("{controller}/{action}/{id}", 
                        new RouteValueDictionary(
                            new { controller = "Default", action = "Index", id = "" }),
                            new HyphenatedRouteHandler())
                );
        

        这里提出了一个非常相似的问题:ASP.net MVC support for URL's with hyphens

        【讨论】:

          【解决方案9】:

          您可以编写一个从 Route 类 GetRouteData 派生的自定义路由来去除破折号,但是当您调用 API 来生成 URL 时,您必须记住包含用于操作名称和控制器名称的破折号。

          这应该不会太难。

          【讨论】:

          • 菲尔是对的(像往常一样)。有一个很好的例子,我不能相信,但我很感激我找到了。它由 MVP 提供,您可以找到它here
          • 这是我用于此实现的 NuGet 包:nuget.org/packages/LowercaseDashedRoute 不要忘记阅读 GitHub 上的 README(通过 NuGet 页面上的项目信息链接)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-18
          • 1970-01-01
          • 2011-02-01
          • 1970-01-01
          • 2014-06-26
          • 2016-01-15
          • 1970-01-01
          相关资源
          最近更新 更多