4

我正在寻找一种自动连字符 CamelCase 操作和视图的方法。也就是说,我希望我不必真正重命名我的视图或为站点中的每个 ActionResult 添加装饰器。

到目前为止,我一直在使用,如此routes.MapRouteLowercase所示。这对于 URL 结构的小写部分非常有效,但对于连字符则无效。所以我最近开始使用Canonicalize(通过 NuGet 安装),但它还没有任何连字符。

我试图...

routes.Canonicalize().NoWww().Pattern("([a-z0-9])([A-Z])", "$1-$2").Lowercase().NoTrailingSlash();

我的正则表达式肯定会按照我想要的方式正确地重构 URL,但是这些 URL 没有被识别,当然。ChangePassword.cshtml例如,该文件仍然是,因此/account/change-password不会指向该文件。

顺便说一句,我对 .NET MVC 还是有点生疏。我已经有几年没有使用它了,而且从 v2.0 开始就没有。

4

4 回答 4

3

这可能有点混乱,但是如果您创建了自定义HttpHandlerRouteHandler,那么这应该可以防止您必须重命名所有视图和操作。您的处理程序可以从请求的操作中去除连字符,这会将“更改密码”更改为更改密码,从而呈现 ChangePassword 操作。

为了简洁起见,代码被缩短了,但重要的部分在那里。

public void ProcessRequest(HttpContext context)
{
    string controllerId = this.requestContext.RouteData.GetRequiredString("controller");
    string view = this.requestContext.RouteData.GetRequiredString("action");

    view = view.Replace("-", "");
    this.requestContext.RouteData.Values["action"] = view;

    IController controller = null;
    IControllerFactory factory = null;

    try
    {
        factory = ControllerBuilder.Current.GetControllerFactory();
        controller = factory.CreateController(this.requestContext, controllerId);

        if (controller != null)
        {
            controller.Execute(this.requestContext);
        }
    }
    finally
    {
        factory.ReleaseController(controller);
    }
}

我不知道我是否以最好的方式实现了它,这或多或少是从我遇到的第一个示例中获取的。我自己测试了代码,所以这确实呈现了正确的操作/视图,并且应该可以解决问题。

于 2011-12-15T01:45:28.640 回答
3

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

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

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

于 2013-08-03T15:25:08.897 回答
0

您是否尝试过使用 URL Rewrite 包?我认为这几乎是您正在寻找的东西。

http://www.iis.net/download/urlrewrite

Hanselman 有一个很好的例子:

http://www.hanselman.com/blog/ASPNETMVCAndTheNewIIS7RewriteModule.aspx

另外,为什么不下载 ReSharper 或 CodeRush 之类的东西,并用它来重构 Action 和 Route 名称呢?这真的很容易,而且非常安全。

花费一小时的重构时间来修复路由/操作命名约定的总体时间要比您尝试根据需要更改路由约定的所有时间花费的时间要少得多。

只是一个想法。

于 2011-12-20T17:58:17.677 回答
0

我在上面接受的答案中尝试了解决方案:使用 Canonicalize Pattern url 策略,然后还添加了一个自定义 IRouteHandler,然后返回一个自定义 IHttpHandler。它大部分工作。这是我发现的一个警告:

使用典型的{controller}/{action}/{id}默认路由,一个名为 的控制器CatalogController,以及其中的一个操作方法,如下所示:

ActionResult QuickSelect(string id){ /*do some things, access the 'id' parameter*/ }

我注意到对“/catalog/quick-select/1234”的请求运行良好,但是对 /catalog/quick-select?id=1234 的请求是 500'ing,因为一旦调用了 action 方法controller.Execute()id参数就是动作方法中的 null 。

我不知道这是为什么,但行为就像 MVC 在模型绑定期间没有查看查询字符串中的值一样。因此ProcessRequest,在接受的答案中,关于实现的一些事情是搞砸了正常的模型绑定过程,或者至少是查询字符串值提供程序。

这是一个交易破坏者,所以我看了一下默认的 MVC IHttpHandler(耶开源!):http ://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/MvcHandler.cs

我不会假装我完全理解了它,但很明显,它在执行过程中所做的ProcessRequest比在接受的答案中所做的要多得多。

所以,如果我们真正需要做的就是从传入的路由数据中去除破折号,以便 MVC 可以找到我们的控制器/动作,为什么我们需要实现一个完整的臭名昭著的 IHttpHandler?我们没有!只需撕掉GetHttpHandler方法中的破折号DashedRouteHandler并将其传递requestContext给开箱即用的方法,MvcHandler这样它就可以执行 252 行魔术,并且您的路由处理程序不必返回二等 IHttpHandler。

tl:博士;- 这就是我所做的:

public class DashedRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            requestContext.RouteData.Values["action"] = requestContext.RouteData.GetRequiredString("action").Replace("-", "");
            requestContext.RouteData.Values["controller"] = requestContext.RouteData.GetRequiredString("controller").Replace("-", "");

            return new MvcHandler(requestContext);
        }
    }
于 2013-10-09T17:17:39.160 回答