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

如何配置中间件实现ASP.NET 7.0 Razor Pages单资源文件本地化?

解决ASP.NET 7.0 Razor Pages单个共享资源文件本地化配置问题

问题根源分析

你遇到的InvalidOperationException: No service for type 'Microsoft.Extensions.Localization.IStringLocalizer' has been registered错误,核心原因是默认未注册非泛型的IStringLocalizer服务,同时你的本地化配置还有几处关键问题:

  1. 启动时直接设置Thread.CurrentThread.CurrentUICulture无法作用于每个请求;
  2. UseRequestLocalization的调用方式不符合规范,需完整配置请求本地化选项;
  3. 页面注入的是非泛型IStringLocalizer,但未关联到你的共享资源文件。

修正后的完整配置

1. 调整Program.cs服务配置与中间件

var builder = WebApplication.CreateBuilder(args);

// 配置本地化资源路径
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

builder.Services.AddDbContext<OWsefaWebContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("OWsefaWebContext") ?? throw new InvalidOperationException("Connection string 'OWsefaWebContext' not found.")));

// 配置Razor Pages本地化,绑定到共享资源
builder.Services.AddRazorPages()
    .AddDataAnnotationsLocalization(opts =>
    {
        opts.DataAnnotationLocalizerProvider = (type, factory) =>
        {
            var assemblyName = typeof(SharedResource).Assembly.GetName().Name;
            return factory.Create(nameof(SharedResource), assemblyName!);
        };
    })
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);

// 可选:注册非泛型IStringLocalizer,使其指向SharedResource(用于页面非泛型注入)
builder.Services.AddSingleton<IStringLocalizer>(sp =>
{
    var factory = sp.GetRequiredService<IStringLocalizerFactory>();
    var assemblyName = typeof(SharedResource).Assembly.GetName().Name;
    return factory.Create(nameof(SharedResource), assemblyName!);
});

// 配置请求本地化选项
var supportedCultures = new[] { "en", "it" };
var localizationOptions = new RequestLocalizationOptions()
    .SetDefaultCulture("en")
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

var app = builder.Build();

using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    DataInitializer.Initialize(services);
}

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

// 正确挂载请求本地化中间件(注意顺序:需在UseRouting之前)
app.UseRequestLocalization(localizationOptions);
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();

2. 调整页面注入代码

如果注册了上述非泛型IStringLocalizer,可保留原注入代码;若想更简洁,推荐直接注入泛型版本(无需额外注册):

@page
@using Microsoft.Extensions.Localization;
@inject IStringLocalizer<SharedResource> localizer
@model OWsefa.Web.Pages.Companies.IndexModel
@{
    ViewData["Title"] = "Index";
}
<h1>Index</h1>
<h1>@localizer["Text.Index"]</h1>

3. 确保资源文件结构正确

在项目根目录创建Resources文件夹,添加对应资源文件:

  • SharedResource.resx(默认语言资源,如英文)
  • SharedResource.it.resx(意大利语资源)
    在资源文件中添加键值对,例如Text.Index对应目标语言的文本内容。

关键修正点说明

  • 移除启动线程的文化设置:请求级别的文化由UseRequestLocalization中间件统一处理,启动线程的文化配置不影响用户请求;
  • 规范RequestLocalizationOptions配置:明确默认文化、支持的文化列表,确保中间件能正确解析请求中的文化标识;
  • 绑定共享资源与本地化服务:无论是数据注解还是页面文本,都明确指向SharedResource,保证所有本地化内容从单个资源文件读取;
  • 泛型IStringLocalizer优先:泛型IStringLocalizer<T>是官方推荐方案,无需额外注册即可直接注入,更符合ASP.NET Core本地化设计规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:10:42