これを行うにはいくつかの方法があります。
URL に表示するスタイルですべてのビューに名前を付けます
これは非常に簡単です。ActionName
すべてのアクションに属性を追加し、URL のスタイルを指定して、CamelCase.cshtml ファイルの名前を camel-case.cshtml ファイルに変更するだけです。
属性ルーティングを使用する
上記と同じように、nuget には属性ルーティングを有効にするプラグインがあり、アクションの属性として各アクションの完全な URL を指定できます。コントローラー名などにも役立つ規則属性があります。私は通常、このアプローチを好みます。これは、アプリケーション内のルートを非常に明確にするのが好きだからです。
よりフレームワーク的なアプローチ
MVC フレームワークを拡張することで、規約に基づいた何かを行うことはおそらく可能ですが、かなりの量の作業になります。コントローラーで正しいアクションを選択するには、フレームワークがコントローラー上のアクションを見つけるために使用する前に、MVC への途中でアクション名を対応する CamelCase にマップする必要があります。これを行う最も簡単な場所は Route です。これは、MVC フレームワークがリクエストを引き継ぐ前に行われる最後の処理です。また、生成された URL が希望どおりに見えるように、途中で逆方向に変換する必要もあります。
ルートを登録するために既存のメソッドを実際に変更したくないので、登録後にすべてのルートをループし、それらを新しい機能でラップする関数をアプリケーションの init に記述するのがおそらく最善です。
これは、あなたがやろうとしていることを達成するアプリケーションの開始へのルートと変更の例です。ただし、ルート属性のアプローチは引き続き使用します。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
WrapRoutesWithNamingConvention(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
private void WrapRoutesWithNamingConvention(RouteCollection routes)
{
var wrappedRoutes = routes.Select(m => new ConventionRoute(m)).ToList();
routes.Clear();
wrappedRoutes.ForEach(routes.Add);
}
private class ConventionRoute : Route
{
private readonly RouteBase baseRoute;
public ConventionRoute(RouteBase baseRoute)
: base(null, null)
{
this.baseRoute = baseRoute;
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var baseRouteData = baseRoute.GetRouteData(httpContext);
if (baseRouteData == null) return null;
var actionName = baseRouteData.Values["action"] as string;
var convertedActionName = ConvertHyphensToPascalCase(actionName);
baseRouteData.Values["action"] = convertedActionName;
return baseRouteData;
}
private string ConvertHyphensToPascalCase(string hyphens)
{
var capitalParts = hyphens.Split('-').Select(m => m.Substring(0, 1).ToUpper() + m.Substring(1));
var pascalCase = String.Join("", capitalParts);
return pascalCase;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
var valuesClone = new RouteValueDictionary(values);
var pascalAction = valuesClone["action"] as string;
var hyphens = ConvertPascalCaseToHyphens(pascalAction);
valuesClone["action"] = hyphens;
var baseRouteVirtualPath = baseRoute.GetVirtualPath(requestContext, valuesClone);
return baseRouteVirtualPath;
}
private string ConvertPascalCaseToHyphens(string pascal)
{
var pascalParts = new List<string>();
var currentPart = new StringBuilder();
foreach (var character in pascal)
{
if (char.IsUpper(character) && currentPart.Length > 0)
{
pascalParts.Add(currentPart.ToString());
currentPart.Clear();
}
currentPart.Append(character);
}
if (currentPart.Length > 0)
{
pascalParts.Add(currentPart.ToString());
}
var lowers = pascalParts.Select(m => m.ToLower());
var hyphens = String.Join("-", lowers);
return hyphens;
}
}
}