ASP.NET Core WebAPI 實作本地化(單資源檔案)

ASP.NET Core WebAPI 實作本地化(單資源檔案)

微軟預設的是一個類別對應多個資源檔案的方式,使用起來是比較麻煩的,本文介紹單資源檔案使用方式,即整個專案所有類別對應一套多語言資源檔案。

最後更新 2022/6/22 下午10:37
HueiFeng
預計閱讀 2 分鐘
分類
ASP.NET Core
標籤
.NET C# ASP.NET Core Web API 本地化

在 Startup ConfigureServices 註冊在地化所需的服務 AddLocalizationConfigure<RequestLocalizationOptions>

public void ConfigureServices(IServiceCollection services)
{
    services.AddLocalization();
    services.Configure<RequestLocalizationOptions>(options =>
    {
        var supportedCultures = new List<CultureInfo>
        {
            new CultureInfo("en-us"),
            new CultureInfo("zh-cn")
        };

        options.DefaultRequestCulture = new RequestCulture(culture: "en-us", uiCulture: "en-us");
        options.SupportedCultures = supportedCultures;
        options.SupportedUICultures = supportedCultures;
        options.RequestCultureProviders = new IRequestCultureProvider[] { new RouteDataRequestCultureProvider { IndexOfCulture = 1, IndexofUiCulture = 1 } };
    });
    services.Configure<RouteOptions>(options =>
    {
        options.ConstraintMap.Add("culture", typeof(LanguageRouteConstraint));
    });
    services.AddControllers();
}

在 Startup.cs 類別的 Configure 方法中新增請求在地化中介軟體。

var localizeOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
            app.UseRequestLocalization(localizeOptions.Value);

RequestCultureProvider 它使用簡單的委派來決定當前的在地化地區設定,當然我們還可以透過 RequestCultureProvider 自訂來源的請求區域資訊,例如設定檔或資料庫都是可以的。或者說我們可以選用預設的一些方式讓我們去取得當前區域。

ASP.NET Core 在地化預設向我們提供了四個方式,可用於決定正在執行的請求的當前地區設定:

  • QueryStringRequestCultureProvider
  • CookieRequestCultureProvider
  • AcceptLanguageHeaderRequestCultureProvider
  • CustomRequestCultureProvider

如下所示我將透過路由的方式,去決定當前區域

public class RouteDataRequestCultureProvider : RequestCultureProvider
{
    public int IndexOfCulture;
    public int IndexofUiCulture;

    public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
    {
        if (httpContext == null)
            throw new ArgumentNullException(nameof(httpContext));
        string uiCulture;

        string culture = uiCulture = httpContext.Request.Path.Value.Split('/')[IndexOfCulture];

        var providerResultCulture = new ProviderCultureResult(culture, uiCulture);

        return Task.FromResult(providerResultCulture);
    }
}

透過如下程式碼片段實現 IRouteConstraint 對路由做相應的約束

public class LanguageRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
    {

        if (!values.ContainsKey("culture"))
            return false;

        var culture = values["culture"].ToString();
        return culture == "en-us" || culture == "zh-cn";
    }
}

新增區域資源檔

[Route("{culture:culture}/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
    private readonly IStringLocalizer<Resource> localizer;
    public HomeController(IStringLocalizer<Resource> localizer)
    {
        this.localizer = localizer;
    }
    public string Get()
    {
        return localizer["Home"];
    }
}

Reference:https://github.com/hueifeng/BlogSample/tree/master/src/LocalizationSingleResx

繼續探索

延伸閱讀

更多文章
同分類 / 同標籤 2022/4/13

ASP.NET Core WebApi 回傳結果統一包裝實務

關於 WebApi 統一結果回傳的時候,讓我也有了更進一步的思考,首先是如何能更好的限制回傳統一的格式,其次是關於結果的包裝一定是更簡單更強大。在不斷的思考和完善中,終於有了初步的成果,便分享出來,學無止境思考便無止境,希望以此能與君共勉。

繼續閱讀