网络 MVC: 如何在我的网址中启用破折号?

我希望在我的网址中使用破折号分隔单词,所以不要使用:

/MyController/MyAction

我想说:

/My-Controller/My-Action

这可能吗?

25730 次浏览

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

这应该不难。

您可以这样使用 ActionName 属性:

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

请注意,然后您需要调用您的视图文件“ My-Action”。”(或适当的扩展名)。您还需要在任何 HTML 中引用“ my-action”。ActionLink 方法。

对于控制器来说,没有这么简单的解决方案。

编辑: 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

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

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())
);

这里提出了一个非常类似的问题: Net MVC 支持带连字符的 URL

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

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

但是这条路线必须注册为 之前你的默认路线。

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

对/my-controller/my-action 的请求可以重写到/mycontroller/myaction,这样就不需要编写自定义处理程序或其他任何东西。访问者得到漂亮的网址,你得到一个 MVC 可以理解。

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

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

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

我对 MVC 还是个新手,所以对此持保留态度。这不是一个优雅的、包罗万象的解决方案,但在 MVC4中给我留下了深刻的印象:

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

我为这个问题开发了一个开源的 NuGet 图书馆,它隐式地将 EveryMvc/Url 转换为 every-mvc/Url。

大写 url 是有问题的,因为 cookie 路径是区分大小写的,互联网的大部分实际上是区分大小写的,而微软的技术将 url 视为不区分大小写的。(更多关于我的博客文章)

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

要安装它,只需在 Visual Studio 中打开 NuGet 窗口,右键单击 Project 并选择 NuGet Package Manager,然后在“ Online”选项卡上键入“ Lowercase Dash Route”,它就会弹出来。

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

Install-Package LowercaseDashedRoute

然后打开 App _ Start/RouteConfig.cs 并注释掉现有的路由:

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

就是这样。所有的 url 都是小写、虚线和隐式转换的,您不需要做任何其他操作。

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

Net MVC 5将支持属性路由,允许对路由名称进行更明确的控制:

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


[HttpPost("mass-hysteria")]
public ViewResult MassHysteria() { }
}

为使用 Asp 的项目获取此行为。在 v5之前的 Net MVC,类似的功能可以在 AttributeRouting 项目(也是 可以作为一种珍品)中找到。事实上,微软找到了 AttributeRouting 的作者,帮助他们实现 MVC 5。

以下是我在 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。

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