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

.NET Core 2迁移至.NET Core 7:Startup.cs本地化配置的适配修改问询

.NET Core 2迁移至.NET Core 7:Startup.cs本地化配置的适配修改问询

嘿,我帮你梳理下从.NET Core 2升级到7时本地化配置的关键修改点和注意事项,这些都是我实际升级项目时踩过的坑,希望对你有用:

一、传统Startup.cs模式的适配修改

如果你的项目还保留着Startup.cs的传统结构,针对你原有的代码可以做这些优化调整:

1. RequestLocalizationOptions配置简化

原代码里先移除再重新创建Cookie请求文化提供者的写法可以优化,直接复用默认实例调整顺序和属性即可,减少不必要的对象创建:

services.Configure<RequestLocalizationOptions>(opts =>
{
    var supportedCultures = new List<CultureInfo>
    {
        new CultureInfo("en"),
        new CultureInfo("ar"),
        new CultureInfo("ar-AE"),
        new CultureInfo("en-GB"),
        new CultureInfo("fr-FR"),
        new CultureInfo("fr"),
        new CultureInfo("en-US"),
    };

    opts.DefaultRequestCulture = new RequestCulture("ar-AE");
    opts.SupportedCultures = supportedCultures;
    opts.SupportedUICultures = supportedCultures;

    // 把Cookie提供者移到第一位,替代原移除再插入的冗余写法
    var cookieProvider = opts.RequestCultureProviders.OfType<CookieRequestCultureProvider>().FirstOrDefault();
    if (cookieProvider != null)
    {
        opts.RequestCultureProviders.Remove(cookieProvider);
        opts.RequestCultureProviders.Insert(0, cookieProvider);
        cookieProvider.CookieName = ".AspNetCore.Culture";
    }
});

2. 本地化服务注册的最佳实践调整

.NET Core 7推荐使用更贴合场景的服务注册方法,同时简化资源程序集的获取逻辑:

services.AddLocalization(options => options.ResourcesPath = "Resources");

// 用AddControllersWithViews替代AddMvc,更清晰地指向MVC场景(如果是Razor页面项目用AddRazorPages)
services.AddControllersWithViews()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization(options =>
    {
        // 简化程序集获取,不用再绕GetTypeInfo的弯子
        var resourceAssembly = typeof(SharedResource).Assembly;
        options.DataAnnotationLocalizerProvider = (type, factory) =>
            factory.Create("SharedResources", resourceAssembly.GetName().Name);
    });

3. 中间件顺序的关键注意点

在Configure方法中,UseRequestLocalization必须放在路由中间件之前,确保本地化设置在路由处理、视图渲染前生效:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 其他前置中间件(比如异常处理、静态文件)
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    // 必须放在UseRouting之前!
    var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
    app.UseRequestLocalization(locOptions.Value);

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting(); // 路由中间件要在本地化之后

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

二、如果改用.NET 7的Top-level Statements(Program.cs)

如果你的项目升级后切换到了Program.cs的顶级语句模式,配置会更简洁,示例如下:

var builder = WebApplication.CreateBuilder(args);

// 注册本地化服务
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

// 配置请求本地化选项
builder.Services.Configure<RequestLocalizationOptions>(opts =>
{
    var supportedCultures = new List<CultureInfo>
    {
        new CultureInfo("en"),
        new CultureInfo("ar"),
        new CultureInfo("ar-AE"),
        new CultureInfo("en-GB"),
        new CultureInfo("fr-FR"),
        new CultureInfo("fr"),
        new CultureInfo("en-US"),
    };

    opts.DefaultRequestCulture = new RequestCulture("ar-AE");
    opts.SupportedCultures = supportedCultures;
    opts.SupportedUICultures = supportedCultures;

    var cookieProvider = opts.RequestCultureProviders.OfType<CookieRequestCultureProvider>().FirstOrDefault();
    if (cookieProvider != null)
    {
        opts.RequestCultureProviders.Remove(cookieProvider);
        opts.RequestCultureProviders.Insert(0, cookieProvider);
        cookieProvider.CookieName = ".AspNetCore.Culture";
    }
});

// 注册MVC服务
builder.Services.AddControllersWithViews()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization(options =>
    {
        var resourceAssembly = typeof(SharedResource).Assembly;
        options.DataAnnotationLocalizerProvider = (type, factory) =>
            factory.Create("SharedResources", resourceAssembly.GetName().Name);
    });

var app = builder.Build();

// 应用本地化设置(必须在路由之前)
var locOptions = app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);

// 其他中间件配置
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

三、.NET Core 7本地化的核心变化注意事项

  • 中间件顺序是重中之重:本地化中间件必须在路由、授权等中间件之前,否则本地化设置不会生效到路由解析、视图渲染或数据注解验证中,这是升级后最容易踩的坑。
  • API简化:.NET Core 3.0+之后,很多反射相关的API(比如GetTypeInfo())已经被简化,直接用typeof(T).Assembly就能获取程序集,不用再做冗余的类型信息转换。
  • 默认请求文化提供者顺序:.NET 7的默认顺序是QueryString→Cookie→AcceptLanguage,你的原代码把Cookie移到第一位的逻辑可以保留,完全符合业务需求。
  • 资源文件逻辑无大变化:Resources文件夹下的资源文件命名规范(比如SharedResources.resx、SharedResources.ar.resx)和.NET Core 2一致,不需要额外调整。
  • 视图代码无需修改:你原来的视图代码@SharedHtmlLocalizer["index"]可以直接复用,只要SharedHtmlLocalizer正确注入即可。

备注:内容来源于stack exchange,提问作者Jeswin Pathrose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 08:49:39