ASP.NET MVCで小文字のルートを使用するにはどうすればよいですか?


145

ASP.NET MVCで小文字のルートと、可能であればアンダースコアを使用するにはどうすればよいですか?だから私は/dinners/details/2電話DinnersController.Details(2)をかけ、可能であれば/dinners/more_details/2電話をかけDinnersController.MoreDetails(2)ますか?

これらすべては、のようなパターンをまだ使用しています{controller}/{action}/{id}


とにかく、さまざまな理由ですべてのルートを手動で作成することになり、CRUD以外の方法でこれを回避するのは難しいと思います。小文字で書いただけです。
プペノ2009

Webフォームを使用しますか?ここに移動:msdn.microsoft.com/en-us/library/…。(プロジェクトを徐々にWebフォームからMVCに変換し、両方をプロジェクト
Jess

これはデフォルトで実行できると確信しています

小文字または大文字でルートを入力するかどうかは重要ではないと思います。

回答:


238

System.Web.Routing 4.5では、RouteCollectionのLowercaseUrlsプロパティを設定することで、これを簡単に実装できます。

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.LowercaseUrls = true;

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

また、SEOの理由でこれを行っているとすると、着信URLを小文字にリダイレクトする必要があります(この記事の多くのリンクで説明されています)。

protected void Application_BeginRequest(object sender, EventArgs e)
{
  //You don't want to redirect on posts, or images/css/js
  bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
  if (isGet && HttpContext.Current.Request.Url.AbsolutePath.Contains(".") == false)    
  {
     string lowercaseURL = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
     if (Regex.IsMatch(lowercaseURL, @"[A-Z]"))
     {
      //You don't want to change casing on query strings
      lowercaseURL = lowercaseURL.ToLower() + HttpContext.Current.Request.Url.Query;

      Response.Clear();
      Response.Status = "301 Moved Permanently";
      Response.AddHeader("Location", lowercaseURL); 
      Response.End();
    }
 }
}

4
これは、4.0で行う最も簡単なことです。
Paul Turner

1
これが一番上にあるといいのですが...ほとんどの貨物が大量のコードを作成しました!
akatakritos 14

2
すばらしい答え:-)後者のSEO部分は、HTTPモジュールにうまく適合します。
David Kirkland

1
@Aaron Sherman Application_BeginRequestの部分はどこでサポートされるのですか?パブリッククラスRouteConfigの内側とifの外側の両方でエラーが発生します。
RichardMišenčík15年

1
@richard-mišenčíkGlobal.asaxファイルに追加
ITmeze

44

これらの2つのチュートリアルは、同じことをしてうまく機能したいときに役立ちました。

http://www.coderjournal.com/2008/03/force-mvc-route-url-lowercase/ http://goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc/

編集:エリアのあるプロジェクトの場合、GetVirtualPath()メソッドを変更する必要があります。

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
  var lowerCaseValues = new RouteValueDictionary();

  foreach (var v in values)
  {
    switch (v.Key.ToUpperInvariant())
    {
      case "ACTION":
      case "AREA":
      case "CONTROLLER":
        lowerCaseValues.Add(v.Key, ((string)v.Value).ToLowerInvariant());
        break;
      default:
        lowerCaseValues.Add(v.Key.ToLowerInvariant(), v.Value);
        break;
    }
  }
  return base.GetVirtualPath(requestContext, lowerCaseValues);
}

9
GONealeリンクが変更されました。URLは現在goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc
Daniel Liuzzi

4
@Derek-いいえ、Areaを使用するとチュートリアルが壊れます。すべてを試してから3日後、より良い解決策を見つけました。属性ルーティングと呼ばれるライブラリがあります。問題を解決し、人生をずっと楽にします。philliphaydon.com/2011/08/...
フィル

6
mvc 4の場合、routes.LowercaseUrls = trueプロパティを使用したより良いソリューションがあります。dhuvelle.com/2012/11/tips-for-aspnet-mvc-4-lowercase-urls.htmlの
Marc

4
@GONealeあなたのURLはどうなりましたか?2番目のリンクが死んでいます!私を笑わせましたが、タイトルは「インターネット上で最高のゴーンエールサイト」です
ルーク

2
@chteuchteuそのリンクは私にはうまくいきませんでしたが、これはうまくいきました。
キューx 2017

22

あなたはASP.NETコアを使用することが起こった場合は、おそらく見ている必要があり、これを

クラスのConfigureServicesメソッドに次の行を追加しますStartup

services.AddRouting(options => options.LowercaseUrls = true);

1
Core 2.0でも同じです。また、stackoverflow.com
a / 45777372/195755

21

UrlHelperを使用してリンクを生成している場合は、アクションとコントローラーの名前を小文字で指定するだけです。

itemDelete.NavigateUrl = Url.Action("delete", "photos", new { key = item.Key });

結果:/ media / photos / delete / 64(コントローラーとアクションがパスカルの場合でも)。


16
この作業を1か所で行うのが最も簡単で標準的なソリューションだと思います。これはインラインCSSと同じくらい悪いです。(どうやら15人がインラインCSSを使用しています)。
マフィンマン

Linuxサーバーにも当てはまりますか?
QMaster

15

Nick BerardiのCoder Journalでこれを見つけましたが、LowercaseRouteクラスの実装方法に関する情報がありませんでした。したがって、追加情報をここに再投稿します。

最初にRouteクラスを拡張してLowercaseRoute

public class LowercaseRoute : Route
{
    public LowercaseRoute(string url, IRouteHandler routeHandler)
        : base(url, routeHandler) { }
    public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
        : base(url, defaults, routeHandler) { }
    public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
        : base(url, defaults, constraints, routeHandler) { }
    public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler) : base(url, defaults, constraints, dataTokens, routeHandler) { }
    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        VirtualPathData path = base.GetVirtualPath(requestContext, values);

        if (path != null)
            path.VirtualPath = path.VirtualPath.ToLowerInvariant();

        return path;
    }
}

次にRegisterRoutes、Global.asax.cs のメソッドを変更します

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new LowercaseRoute("{controller}/{action}/{id}", 
        new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), 
        new MvcRouteHandler()));

    //routes.MapRoute(
    //    "Default",                                              // Route name
    //    "{controller}/{action}/{id}",                           // URL with parameters
    //    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
    //);
}

しかし、routes.MapRouteを使用する方法を知りたいのですが...


GONealeの記事は拡張メソッドを提供しているのでroutes.MapRouteLowercase(...、上記よりも優れた書き込みができます。goneale.wordpress.com
Drew Noakes

1
GONealeのブログ全体が姿を消した。同様のコンテンツ(および同じ拡張方法)を持つ別のブログエントリ次に示します。重複コンテンツの削減という状況でこの状況に対処します。
パトリッジ'29

11

このクラスをRouteCollectionの拡張として追加することにより、MapRoute構文を引き続き使用できます。

public static class RouteCollectionExtension
{
    public static Route MapRouteLowerCase(this RouteCollection routes, string name, string url, object defaults)
    {
        return routes.MapRouteLowerCase(name, url, defaults, null);
    }

    public static Route MapRouteLowerCase(this RouteCollection routes, string name, string url, object defaults, object constraints)
    {
        Route route = new LowercaseRoute(url, new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(defaults),
            Constraints = new RouteValueDictionary(constraints)
        };

        routes.Add(name, route);

        return route;
    }
}

これで、アプリケーションのスタートアップで「MapRoute」の代わりに「MapRouteLowerCase」を使用できます。

    public void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // Url shortcuts
        routes.MapRouteLowerCase("Home", "", new { controller = "Home", action = "Index" });
        routes.MapRouteLowerCase("Login", "login", new { controller = "Account", action = "Login" });
        routes.MapRouteLowerCase("Logout", "logout", new { controller = "Account", action = "Logout" });

        routes.MapRouteLowerCase(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );
    }

これを読んで、誰のために、LowercaseRouteから来るように見えます上記の最初のコードスニペット内のクラスこの他の答え
chueは、X

6

これには実際には2つの答えがあります。

  1. あなたはすでにこれを行うことができます:ルートエンジンは大文字と小文字を区別しない比較を行います。小文字のルートを入力すると、適切なコントローラーとアクションにルーティングされます。
  2. ルートリンクを生成するコントロール(ActionLink、RouteLinkなど)を使用している場合、このデフォルトの動作をオーバーライドしない限り、大文字と小文字が混在するリンクが生成されます。

ただし、アンダースコアは自分で決めます...


2

ActionName属性を使用できますか?

 [ActionName("more_details")]
 public ActionResult MoreDetails(int? page)
 {

 }

事件は関係ないと思います。URLのMore_Details、more_DETAILS、mOrE_DeTaILsはすべて、同じコントローラーアクションに移動します。


私はそれを試していません-どちらかを使用できますか?( "moredetails"または "more_details")
GalacticCowboy

フォローアップするために私は試してみましたが、指定された名前を使用する必要があるため、いいえ、どちらの方法でも処理することはできません。また、コントローラーアクションとビューの作成方法によっては、ビューの名前を明示的に指定する必要がある場合があります。
GalacticCowboy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.