14

私はroutes.LowercaseUrls = true;うまく機能しているMVC 4アプリケーションで使用しています。ただし、パラメーターも小文字になるため、次のようなルートがある場合

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

で生成されたリンク

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

URLの{hash}- 部分も小文字になります。たとえばViewBag.MyHash = "aX3F5U"、生成されたリンク/foo/ax3f5u/foo/aX3F5U

MVC にコントローラーとアクション部分のみを小文字にするよう強制する方法はありますか?

MVC の古いバージョンでは、のカスタム サブクラスを実装する方法のように見えましたが、ルート コンストラクターのシグネチャがかなり異なるため、Routeどのように/どこでインスタンス化するかわかりません。MapRouteより簡単な方法になります。

4

4 に答える 4

2

これを行う簡単な方法の 1 つを次に示します。

public class MyRoute : Route
{
    public MyRoute(string url, object defaults): base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
    { 
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        if (values["action"] != null)
            values["action"] = values["action"].ToString().ToLowerInvariant();
        if (values["controller"] != null)
            values["controller"] = values["controller"].ToString().ToLowerInvariant();
        return base.GetVirtualPath(requestContext, values);
    }
}

routes.Add("Default",new MyRoute("{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = MyUrlParameter.Optional }));

詳細については、このブログ投稿を参照してください。

于 2013-03-17T11:52:45.207 に答える
2

のカスタムサブクラスを使用したソリューションは、十分にシンプルであると思いますRouteが、同時に少し醜いです:)

CustomRouteのatRegisterRouteメソッドを追加できますRouteConfig.cs。の代わりに次のコードを追加します。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);

特定の実装は次の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完全な例では、拡張 onとカスタム子の組み合わせを使用して、元の構文Routeにできるだけ近づけることができます。routes.MapRoute(...)

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の代わりに使用できるMapRouteようになりました。

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" }
);

望ましい行動を明らかにする。

于 2013-03-16T22:24:49.203 に答える
0

privateRouteCollection.NormalizeVirtualPathメソッドを見ると、単純に を使用していることがわかりますvirtualPath.ToLowerInvariant()。したがって、それを処理する方法はありません。独自のルートを作成しても、小文字になります。

しかし、できることは、「#」記号 ie の後にハッシュを追加することです"foo/{action}/#{hash}"。私は試していませんが、うまくいくはずです。NormalizeVirtualPath実装を見てください。

于 2013-03-17T09:38:10.440 に答える
-1

1.2.3 のように単純です。

この例を見てください

   routes.MapRouteLowercase( // changed from routes.MapRoute
       "Default",
       "{controller}/{action}/{id}",
       new { controller = "Home", action = "Index", id = UrlParameter.Optional }
   );

Nuget経由でダウンロードしてインストールするのは簡単です。私はそれを使用しています。 PM> Install-Package LowercaseRoutesMVC

http://lowercaseroutesmvc.codeplex.com/

于 2013-03-17T06:08:07.547 に答える