You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用RESX文件的情况下实现.NET MAUI本地化

不使用RESX,通过Web API实现MAUI Hybrid/Blazor WASM本地化

MAUI Hybrid 实现方案

1. 定义本地化实体与服务接口

先定义存储翻译数据的实体类,以及统一的本地化服务接口:

// 翻译内容实体
public class Translation
{
    public string Key { get; set; }
    public string Culture { get; set; }
    public string Value { get; set; }
}

// 本地化服务接口
public interface ILocalizationService
{
    Task<Dictionary<string, string>> GetTranslationsAsync(string culture);
}

2. 实现Web API调用的本地化服务

实现接口,调用后端API获取翻译数据,并加入内存缓存减少重复请求:

public class ApiLocalizationService : ILocalizationService
{
    private readonly HttpClient _httpClient;
    private readonly Dictionary<string, Dictionary<string, string>> _cache = new();

    public ApiLocalizationService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<Dictionary<string, string>> GetTranslationsAsync(string culture)
    {
        // 优先从缓存读取
        if (_cache.TryGetValue(culture, out var translations))
            return translations;

        // 调用API获取数据
        var response = await _httpClient.GetFromJsonAsync<List<Translation>>($"api/localization/{culture}");
        if (response == null)
            return new Dictionary<string, string>();

        // 转换为字典并存入缓存
        translations = response.ToDictionary(t => t.Key, t => t.Value);
        _cache[culture] = translations;
        return translations;
    }
}

3. 注册服务到依赖注入容器

在MauiProgram.cs中注册HttpClient和本地化服务:

builder.Services.AddHttpClient<ILocalizationService, ApiLocalizationService>(client =>
{
    client.BaseAddress = new Uri("https://your-api-domain.com/");
});

4. 创建本地化标记扩展(便于XAML调用)

写一个标记扩展类,直接在XAML中绑定翻译内容:

[ContentProperty(nameof(Key))]
public class TranslateExtension : IMarkupExtension<BindingBase>
{
    public string Key { get; set; }

    public BindingBase ProvideValue(IServiceProvider serviceProvider)
    {
        var localizationService = serviceProvider.GetService<ILocalizationService>();
        var currentCulture = CultureInfo.CurrentUICulture.Name;

        return new Binding
        {
            Source = localizationService.GetTranslationsAsync(currentCulture).Result,
            Path = $"[{Key}]",
            Mode = BindingMode.OneWay
        };
    }

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
    {
        return ProvideValue(serviceProvider);
    }
}

在XAML中使用:

<ContentPage xmlns:local="clr-namespace:YourAppNamespace">
    <Label Text="{local:Translate WelcomeMessage}" />
</ContentPage>

Blazor WASM 实现方案

1. 复用实体与服务接口

直接使用MAUI部分定义的Translation实体和ILocalizationService接口即可。

2. 实现带缓存的API本地化服务

public class ApiLocalizationService : ILocalizationService
{
    private readonly HttpClient _httpClient;
    private readonly IMemoryCache _cache;

    public ApiLocalizationService(HttpClient httpClient, IMemoryCache cache)
    {
        _httpClient = httpClient;
        _cache = cache;
    }

    public async Task<Dictionary<string, string>> GetTranslationsAsync(string culture)
    {
        var cacheKey = $"translations_{culture}";
        if (_cache.TryGetValue(cacheKey, out Dictionary<string, string> translations))
            return translations;

        translations = await _httpClient.GetFromJsonAsync<Dictionary<string, string>>($"api/localization/{culture}") 
            ?? new Dictionary<string, string>();

        // 缓存1小时
        _cache.Set(cacheKey, translations, TimeSpan.FromHours(1));
        return translations;
    }
}

3. 注册服务与自定义IStringLocalizer

为了兼容Blazor原生的本地化注入方式,自定义IStringLocalizer实现:

public class ApiStringLocalizer : IStringLocalizer
{
    private readonly ILocalizationService _localizationService;
    private readonly string _currentCulture;

    public ApiStringLocalizer(ILocalizationService localizationService)
    {
        _localizationService = localizationService;
        _currentCulture = CultureInfo.CurrentUICulture.Name;
    }

    public LocalizedString this[string name]
    {
        get
        {
            var translations = _localizationService.GetTranslationsAsync(_currentCulture).Result;
            var value = translations.TryGetValue(name, out var val) ? val : name;
            return new LocalizedString(name, value);
        }
    }

    public LocalizedString this[string name, params object[] arguments]
    {
        get
        {
            var rawValue = this[name].Value;
            var formatted = string.Format(rawValue, arguments);
            return new LocalizedString(name, formatted);
        }
    }

    public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
    {
        var translations = _localizationService.GetTranslationsAsync(_currentCulture).Result;
        return translations.Select(kv => new LocalizedString(kv.Key, kv.Value));
    }

    public IStringLocalizer WithCulture(CultureInfo culture)
    {
        // 可选:实现多文化切换逻辑
        return new ApiStringLocalizer(_localizationService);
    }
}

// 泛型版本,支持组件级注入
public class ApiStringLocalizer<T> : IStringLocalizer<T>
{
    private readonly IStringLocalizer _localizer;

    public ApiStringLocalizer(ILocalizationService localizationService)
    {
        _localizer = new ApiStringLocalizer(localizationService);
    }

    public LocalizedString this[string name] => _localizer[name];
    public LocalizedString this[string name, params object[] arguments] => _localizer[name, arguments];
    public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures) => _localizer.GetAllStrings(includeParentCultures);
    public IStringLocalizer WithCulture(CultureInfo culture) => _localizer.WithCulture(culture);
}

在Program.cs中注册服务:

builder.Services.AddHttpClient<ILocalizationService, ApiLocalizationService>(client =>
{
    client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
});
builder.Services.AddMemoryCache();
builder.Services.AddSingleton(typeof(IStringLocalizer<>), typeof(ApiStringLocalizer<>));

4. 在Blazor组件中使用

@inject IStringLocalizer<Index> Localizer

<h1>@Localizer["WelcomeMessage"]</h1>
<p>@Localizer["Greeting", "John"]</p>

内容的提问来源于stack exchange,提问作者kazou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:45:44