【问题标题】:Satellite Assembly, ASP.NET language not changing卫星程序集,ASP.NET 语言不变
【发布时间】:2012-12-05 14:43:11
【问题描述】:

我正在转换一个项目以使用附属程序集。 我创建了一个新的类库(名为“资源”)。所有默认资源都位于根级别*.resx。 然后每种文化都有一个文件夹。

"zh/" *.en.resx

zh-CN/ *.en-GB.resx

我将 .resx 文件 Access Modifier 更改为“公共”并更改了这些设置。

BuildAction: EmbeddedResource
CopyToOutputDirectory: CopyAlways

我确保.resx 设计师*.Designer.cs 使用“资源”命名空间。

我将类库添加到 ASP.NET MVC 应用程序中,并在 global.asax.cs 中根据需要设置文化。

System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");

我尝试将al.exeResgen.exe 命令添加到资源类库中的构建后事件。

"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\Resgen.exe" en-GB/MyResourceFile.en-GB.resx "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\al.exe" /t:lib /embed:en-GB/MyResourceFile.en-GB.resources /culture:en-gb /out:Resources.resources.dll

查看 MVC 应用程序 bin/ 文件夹内,每种语言都有 3 个文件的文件夹:

MyResources.en-GB.Designer.cs、MyResources.en-GB.resx、 资源.resources.dll

根级别只有Resources.dllResources.resources.dll,但默认语言可以正常工作。第二个*.resources.dll 是由于构建后事件。

当我更改 CurrentUICulture 时,它​​不会更改 UI 语言。在将资源从App_GlobalResources/ 移出到外部程序集之前,它运行良好(Razor 示例)。

@Resources.MyResources.StringIdentifier 

使用 .NET Reflector 查看资源 .dlls 有这些差异。

Satellite Resources: (Project: Resources)
Resources.en_GB.MyResources.en-GB.resources 
App_GlobalResources: (Project MVCApp)
Namespace.MVCApp.App_GlobalResources.MyResources.en-GB.resources

编辑:

global.asax.cs 中设置 CurrentCulture 和 UICulture 后,我测试了手动检索 ResourceManager 的实际工作并以预期语言检索字符串。

            System.Resources.ResourceManager gStrings =
                new System.Resources.ResourceManager("Resources.MyResources", System.Reflection.Assembly.Load("Resources")); // Resources=Project Name
            string test = gStrings.GetString("TestString"); // WORKS IN GLOBAL.ASAX.CS!!!

我在 MVC 控制器中尝试了相同的测试,但它不起作用。所以唯一可以检索到 ResourceManager 的地方是 Global.asax.cs。

奇怪的是,在 razor 中 UI 级别的相同测试只会返回默认的文化文本! CultureInfo 是正确的,但 ResourceManager 仅返回 ASP.NET MVC Razor UI 中的默认语言。 (这只是为了测试)

    @{  
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentUICulture;
        System.Resources.ResourceManager gStrings =
            new System.Resources.ResourceManager("Resources.MyResource", System.Reflection.Assembly.Load("Resources"));
        string s = gStrings.GetString("Test");    // DOESN'T WORK IN UI
    }

TLDR 版本:

从 App_GlobalResources 的资源 (.resx) 转换为附属程序集。

手头的问题。

我可以手动调用卫星程序集的 ResourceManager,使用 global.asax 中的 CurrentUICulture 语言,它可以按预期工作,但是相同的测试在 UI 端失败并且在 MVC 控制器中失败。

默认语言可以正常使用,为什么 UI 不切换语言?

【问题讨论】:

    标签: asp.net asp.net-mvc localization satellite-assembly


    【解决方案1】:

    如果最近建立了一个项目,其中内部化或多或少像您描述的那样正常工作。

    https://github.com/Jacco/Perpetuality

    我在用作基础的控制器中的 OnAuthorize 中切换每个 HTTP 请求的语言:

    using Perpetuality.Data;
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Security.Principal;
    using System.Threading;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    
    namespace Perpetuality.Controllers
    {
        public partial class BaseController : Controller
        {
            private CultureInfo GetCultureInfo(AuthorizationContext filterContext)
            {
                switch ((string)filterContext.RouteData.Values["language"])
                {
                    case "nl":
                        return CultureInfo.CreateSpecificCulture("nl-NL");
                    case "en":
                        return CultureInfo.CreateSpecificCulture("en-US");
                    case "pt":
                        return CultureInfo.CreateSpecificCulture("pt-PT");
                    case "de":
                        return CultureInfo.CreateSpecificCulture("de-DE");
                    case "es":
                        return CultureInfo.CreateSpecificCulture("es-ES");
                    case "fr":
                        return CultureInfo.CreateSpecificCulture("fr-FR");
                    case "it":
                        return CultureInfo.CreateSpecificCulture("it-IT");
                    case "jp":
                        return CultureInfo.CreateSpecificCulture("ja-JP");
                    default:
                        return CultureInfo.CreateSpecificCulture("en-US");
                }
            }
    
            protected override void OnAuthorization(AuthorizationContext filterContext)
            {
                Thread.CurrentThread.CurrentCulture = GetCultureInfo(filterContext);
                Thread.CurrentThread.CurrentUICulture = GetCultureInfo(filterContext);
    
                base.OnAuthorization(filterContext);
            }
        }
    }
    

    在我的项目中,RESX 文件的指定方式与您的不同:

    BuildAction: EmbeddedResource
    CopyToOutputDirectory: DoNotCopy
    

    在我的 vie 中,我访问这样的字符串:

    @Resources.Home.Index.FacebookButtonCaption
    

    我没有设置任何后期或预构建。

    在我的项目中,语言总是在 url 上。如果最初没有选择合适的语言,用户可以切换语言。

    【讨论】:

    • +1 用于分享。我使用 cookie 作为语言,所以只设置了文化,例如登录时。我还需要一段时间才能有机会详细调查您的应用程序(以及它是否真的适用于卫星资源),感谢您的发帖。它们有点棘手,在多个项目中使用时需要相当繁琐的细节。 :)
    • 我认为您需要为每个传入的请求设置文化。从 cookie 中获取它是好的。我的资源也在一个单独的库中(我认为这就是您所说的卫星?)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多