ASP.NET CORE MVCマイナス区切りスタイルを実現するURL

7463 ワード

ASP.NET CORE MVCでは、デフォルトのRouteテンプレートは/{controller}/{action}です.URL小文字変換をオンにすることでURLを小文字にすることができますが、ControllerまたはActionがフレーズになった場合、生成されるURLは友好的ではありません.UserControllerメソッドとAddUserメソッドがあると仮定すると、フレームワークで生成されるURLは、/User/AddUserであり、小文字変換をオンにした場合、/user/adduserである可能性があります.大文字を含むURLは問題ありませんが、小文字のURLはもっと一般的ですが、小文字を完全に変換するとURLの可読性が悪いという問題があります.この文書では、フレームワークがマイナス記号で区切られたスタイルのURLを生成するのに役立つコードを提供します.これらのコードが適用されると、生成されたURLは/user/add-userのようになります.Microsoftは、ControllerまたはActionにタグを付けてアクセスパスをカスタマイズできるRouteAttributeを提供しています.この方法は非常に強力ですが、プロジェクトが大きい場合には使用が煩雑です.何しろ、コントローラやアクションごとに手動でタグを付ける作業も少なくありません.ASP.NET CORE MVCフレームワークにはIControllerModelConventionインタフェースが定義されており、動作時にActionにRouteモデルを追加することができます.プロジェクトにDashedRoutingConventionクラスファイルを新規作成します.コードは次のとおりです.
    public class DashedRoutingConvention : IControllerModelConvention
    {
        public void Apply(ControllerModel controller)
        {
            var hasRouteAttributes = controller.Selectors.Any(selector =>
                selector.AttributeRouteModel != null);
            if (hasRouteAttributes)
            {
                // This controller manually defined some routes, so treat this 
                // as an override and not apply the convention here.
                return;
            }

            foreach (var controllerAction in controller.Actions)
            {
                foreach (var selector in controllerAction.Selectors.Where(x => x.AttributeRouteModel == null))
                {
                    var parts = new List<string>();
                    foreach (var attr in controller.Attributes)
                    {
                        if (attr is AreaAttribute area)
                        {
                            parts.Add(area.RouteValue);
                        }
                    }

                    if (
                        parts.Count == 0
                        && controller.ControllerName == "Home"
                        && controllerAction.ActionName == "Index"
                    )
                    {
                        continue;
                    }

                    parts.Add(PascalToKebabCase(controller.ControllerName));

                    if (controllerAction.ActionName != "Index")
                    {
                        parts.Add(PascalToKebabCase(controllerAction.ActionName));
                    }

                    selector.AttributeRouteModel = new AttributeRouteModel
                    {
                        Template = string.Join("/", parts)
                    };
                }
            }
        }

        private static string PascalToKebabCase(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return value;
            }

            return Regex.Replace(
                    value,
                    "(?",
                    "-$1",
                    RegexOptions.Compiled)
                .Trim()
                .ToLower();
        }
    }

その後、DashedRoutingConventionをStartup.csに登録します.
public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc(options => options.Conventions.Add(new DashedRoutingConvention()));
}

 
これで、すべてのコードが完了します.Notices:
  • このコードはAreaをサポートし、Area名もエスケープします.
  • 本コードは、カスタムルーティング方式で機能を実現するため、事前定義されたルーティングに影響を及ぼす可能性がある.
  • ルーティングに関する詳細については、以下を参照してください.https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing
  • このコードは他のコードを参照しています.詳細は、次のとおりです.https://stackoverflow.com/questions/40334515/automatically-generate-lowercase-dashed-routes-in-asp-net-core
  • 私たちは忙しいライセンスセンターでこのコードを有効にしました.プレゼンテーション:https://passport.coderbusy.com/