前回作成した .NET 8.0 + ASP.NET Core(MVC) で実装する クエリベースローカライズ処理(多国言語対応) を、ルートベースローカライズへ変更したサンプルを作成しました。
ソースコードは GitHub で公開しています。
クエリベースローカライズ:クエリ文字列での言語切替
ルートベースローカライズ:URLパス先頭での言語切替 ※ASP.NET Core 公式推奨
ソースコード変更内容を解説

WebApplication1/Program.cs
RequestCultureProvidersと UseRequestLocalizationを追加し、cultureは URLのルートプレフィックスから取得すると明示。
URLのパターンに cultureを追加。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
using Microsoft.AspNetCore.Localization.Routing; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.Options; var builder = WebApplication.CreateBuilder(args); builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { "ja", "en" }; options.SetDefaultCulture(supportedCultures[0]) .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); }); builder.Services.AddMvc() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) .AddDataAnnotationsLocalization(); // Add services to the container. builder.Services.AddControllersWithViews() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) .AddDataAnnotationsLocalization(); builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new System.Globalization.CultureInfo("en"), new System.Globalization.CultureInfo("ja") }; options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("ja"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; options.RequestCultureProviders = new[] { new RouteDataRequestCultureProvider { Options = options } }; }); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseRequestLocalization( app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value ); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{culture=ja}/{controller=Home}/{action=Index}/{id?}"); app.Run(); |
WebApplication1/Views/Shared/_Layout.cshtml
言語選択用のコンボボックスを追加。
コードブロックで cultureを取得し、コンボボックスの選択状態(selected)の条件分岐に使用。
コードブロックで controller、action、Queryを取得し、コンボボックスの onchangeイベントにある、JavaScriptでページ遷移する際の URLに使用。


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
@{ var culture = ViewContext.RouteData.Values["culture"]?.ToString()?.ToLower() ?? "ja"; var ctrl = ViewContext.RouteData.Values["controller"]?.ToString() ?? "Home"; var act = ViewContext.RouteData.Values["action"]?.ToString() ?? "Index"; var query = Context.Request.QueryString.ToUriComponent(); // ?id=1&page=2 など } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - WebApplication1</title> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" /> <link rel="stylesheet" href="~/WebApplication1.styles.css" asp-append-version="true" /> </head> <body> <header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container-fluid"> <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">WebApplication1</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between"> <ul class="navbar-nav flex-grow-1"> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> </li> </ul> </div> </div> </nav> </header> <form method="get" style="display:inline;"> <select name="culture" onchange=" const c=this.value; const query='@query' ; let url='/' + c + '/@ctrl/@act' ; if (query && query.length> 0) url += query; window.location.href = url; "> @if (culture == "ja") { <text> <option value="ja" selected>日本語</option> <option value="en">English</option> </text> } else { <text> <option value="ja">日本語</option> <option value="en" selected>English</option> </text> } </select> </form> <div class="container"> <main role="main" class="pb-3"> @RenderBody() </main> </div> <footer class="border-top footer text-muted"> <div class="container"> © 2025 - WebApplication1 - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> </div> </footer> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @await RenderSectionAsync("Scripts", required: false) </body> </html> |
コメント