Asp.Net MVC:如何在网址中启用破折号?


Answers:


155

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

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

请注意,然后您需要将您的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

1
这是真正的答案。不知道为什么Phil没有添加此信息
Eduardo Molteni

2
不错的提示。只需添加:使用默认的View()调用执行此操作时,除非明确指定原始名称,否则MVC会在Views文件夹中的某个位置而不是“ MyAction.aspx”中搜索“ My-Action.aspx”。
Nicholas Piasecki

@Eduardo我认为Action 5属性是为预览5添加的,预览5是在Phil发表后发布的。
大卫·科拉尔

如何显式指定视图文件名?我是否必须将视图文件名更改为My-Action.aspx?
亚历克斯(Alex)2010年

4
@LordofScripts-确保已使用以下命令正确配置了路由:routes.MapMvcAttributeRoutes();
乍得2014年

16

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

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对带连字符的URL的支持


11

我已经开发了一个开源的NuGet库针对此问题,该将EveryMvc / Url隐式转换为every-mvc / url。

大写网址存在问题,因为Cookie路径区分大小写,大多数Internet实际上是区分大小写的,而Microsoft技术将网址视为不区分大小写。(有关我的博客文章的更多信息

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的解决方案。谢谢
Barryman9000 2015年

非常感谢。
David

8

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

文章让我得出这样的结论。希望对您有用。


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项目中找到类似的功能(也可以作为nuget使用)。实际上,Microsoft与AttributeRouting的作者联系,以帮助他们实现MVC 5的实现。


1
哇,没人提到《捉鬼敢死队》参考书吗?
Erik Philips

1

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

那不应该太难。


菲尔(通常)是正确的。有一个很好的例子,我不能称赞,但是我很感激我发现。是由MVP制作的,您可以在此处找到。
Daniel Cox

这是我用于该实现的NuGet软件包:nuget.org/packages/LowercaseDashedRoute不要忘记阅读GitHub上的README(通过NuGet页面上的Project Info链接)
Ata

1

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

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

但是必须您的默认路由之前注册此路由。


同样,使用AttributeRouting可让您指定所需的任何路由名称,并具有额外的好处,即准确了解操作与哪个路由相关联。
Jim Geurts

0

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

可以将对/ my-controller / my-action的请求重写为/ mycontroller / myaction,然后无需编写自定义处理程序或其他任何内容。访客会得到漂亮的URL,而您会得到MVC可以理解的URL。

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

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

可能的不利之处是您必须将项目切换为使用IIS Express或IIS,以便在开发过程中进行重写。


0

我对MVC还是很陌生,所以要加一点盐。这不是一个优雅的,万能的解决方案,但在MVC4中为我成功了:

routes.MapRoute(
    name: "ControllerName",
    url: "Controller-Name/{action}/{id}",
    defaults: new { controller = "ControllerName", action = "Index", id = UrlParameter.Optional }
);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.