在路由参数preserve案例与LowercaseUrls启用 [英] Preserve Case in Route Parameters with LowercaseUrls enabled

查看:154
本文介绍了在路由参数preserve案例与LowercaseUrls启用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 routes.LowercaseUrls = TRUE; 在我的MVC应用4这是伟大的工作。然而,参数也将获得小写,所以如果我有像

I am using routes.LowercaseUrls = true; in my MVC 4 application which is working great. However, parameters will also get lowercased, so if I have a route like

routes.MapRoute(
    name: "MyController",
    url: "foo/{hash}/{action}",
    defaults: new { controller = "MyController", action = "Details" }
);

@Html.ActionLink("my link", "Details", new { hash=ViewBag.MyHash })

将有 {哈希} 双组分如 ViewBag.MyHash =aX3F5U小写为好,例如URL的然后将生成的链接将 /富/ ax3f5u 而不是 /富/ aX3F5U

will have the {hash}-part of the URL lowercased as well, for example if ViewBag.MyHash = "aX3F5U" then the generated link will be /foo/ax3f5u instead of /foo/aX3F5U

有没有办法强制MVC只有小写控制器和动作部分?

Is there a way to force MVC to only lowercase the controller and action parts?

对于旧版本的MVC的,要走的路似乎是实施路线,但是我不知道如何/在哪里进行实例化的自定义子类,由于路径构造函数的签名是完全不同的,以图路线,我希望那里是一个简单的方法。

For older versions of MVC, the way to go seemed to be to implement a custom subclass of Route, however I don't know how/where to instantiate it, since the signature of the route constructors is quite different to MapRoute and I'm hoping there to be a simpler way.

推荐答案

我觉得跟路线的自定义子类的解决方案就足够了良好而简单,但在同时有点难看:)

I think the solution with a custom subclass of Route will be a good enough and simple, but at the same time a little bit ugly :)

您可以添加 RouteConfig.cs CustomRoute RegisterRoute 方法C $ C>。添加以下code,而不是 routes.MapRoute

You can add a CustomRoute at RegisterRoute method of RouteConfig.cs. Add the following code instead of routes.MapRoute

var route = new CustomRoute(new Route(
  url: "{controller}/{action}/{id}",
  defaults: new RouteValueDictionary() { 
    { "controller", "Home" }, 
    { "action", "Index" }, 
    { "id", UrlParameter.Optional }
  },
  routeHandler: new MvcRouteHandler()
));
routes.Add(route);

特别Implementaion CustomRoute 可能是这样的:

public class CustomRoute : RouteBase
{
  private readonly RouteBase route;

  public CustomRoute(RouteBase route)
  {
    this.route = route;
  }

  public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
  {
    values = new RouteValueDictionary(values.Select(v =>
    {
      return v.Key.Equals("action") || v.Key.Equals("controller")
        ? new KeyValuePair<String, Object>(v.Key, (v.Value as String).ToLower())
        : v;
    }).ToDictionary(v => v.Key, v => v.Value));

    return route.GetVirtualPath(requestContext, values);
  }

  public override RouteData GetRouteData(HttpContextBase httpContext)
  {
    return route.GetRouteData(httpContext);
  }
}

但它不是一个最优实现。一个完整的例子可以使用在 RouteCollection 和一个自定义路线子扩展名的组合,以保持它尽可能接近到原 routes.MapRoute(...)语法:

However it's not an optimal implementation. A complete example could use a combination of extensions on RouteCollection and a custom Route child to keep it as close as possible to the original routes.MapRoute(...) syntax:

LowercaseRoute类:

public class LowercaseRoute : Route
{
    public LowercaseRoute(string url, IRouteHandler routeHandler) : base(url, routeHandler) { }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        values = new RouteValueDictionary(values.Select(v =>
        {
            return v.Key.Equals("action") || v.Key.Equals("controller")
              ? new KeyValuePair<String, Object>(v.Key, (v.Value as String).ToLower())
              : v;
        }).ToDictionary(v => v.Key, v => v.Value));

        return base.GetVirtualPath(requestContext, values);
    }
}

RouteCollectionExtensions类:

public static class RouteCollectionExtensions
{
    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url)
    {
        return MapLowercaseRoute(routes, name, url, null /* defaults */, (object)null /* constraints */);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults)
    {
        return MapLowercaseRoute(routes, name, url, defaults, (object)null /* constraints */);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults, object constraints)
    {
        return MapLowercaseRoute(routes, name, url, defaults, constraints, null /* namespaces */);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, string[] namespaces)
    {
        return MapLowercaseRoute(routes, name, url, null /* defaults */, null /* constraints */, namespaces);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces)
    {
        return MapLowercaseRoute(routes, name, url, defaults, null /* constraints */, namespaces);
    }

    [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
    public static Route MapLowercaseRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
    {
        if (routes == null)
        {
            throw new ArgumentNullException("routes");
        }
        if (url == null)
        {
            throw new ArgumentNullException("url");
        }

        Route route = new LowercaseRoute(url, new MvcRouteHandler())
        {
            Defaults = CreateRouteValueDictionary(defaults),
            Constraints = CreateRouteValueDictionary(constraints),
            DataTokens = new RouteValueDictionary()
        };

        if ((namespaces != null) && (namespaces.Length > 0))
        {
            route.DataTokens["Namespaces"] = namespaces;
        }

        routes.Add(name, route);

        return route;
    }

    private static RouteValueDictionary CreateRouteValueDictionary(object values)
    {
        var dictionary = values as IDictionary<string, object>;
        if (dictionary != null)
        {
            return new RouteValueDictionary(dictionary);
        }

        return new RouteValueDictionary(values);
    }
}

您现在可以使用 MapLowercaseRoute 而不是图路线,所以

You can now use MapLowercaseRoute instead of MapRoute, so

routes.MapRoute(
    name: "MyController",
    url: "foo/{hash}/{action}",
    defaults: new { controller = "MyController", action = "Details" }
);

简直变成

routes.MapLowercaseRoute(
    name: "MyController",
    url: "foo/{hash}/{action}",
    defaults: new { controller = "MyController", action = "Details" }
);

暴露所需的行为。

exposing the desired behaviour.

这篇关于在路由参数preserve案例与LowercaseUrls启用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆