从ASP.NET中的标准程序集覆盖资源

wRA*_*RAR 7 asp.net localization satellite-assembly

我想覆盖一个System.ComponentModel.DataAnnotationsASP.NET项目的字符串.我是否需要制作附属程序集,搞乱自定义构建任务al.exe等?即使是,我也找不到如何转换.resx.resources将其提供给al.exe.如果没有,在哪里放.resx.以及如何命名它?

UPD:说清楚:我想使用自定义资源字符串而不是程序集中的默认资源中的一个.我不想在使用该字符串的每个地方进行更改.毕竟,资源只是为了覆盖它们而存在.

Voi*_*ler 5

Phil Haack 有一篇出色的文章Localizing ASP.Net MVC Validation,它专门指导您覆盖字符串。这篇文章DataAnnotations比它更适用ASP.net MVC。因此,这将有助于您使用DataAnnotattions

下面我列出了在 Visual Studio 中添加本地化资源的最简单步骤。

  1. 打开Project Properties对话框。
  2. 选择Resources选项卡。
  3. 单击以创建新的默认资源文件
  4. 这将在您的Properties文件夹中创建两个文件。
    • 资源.resx
    • 资源.Designer.cs
  5. Resources.resx打开时,将其更改Access ModifierPublic.
  6. 添加你的字符串。

要为特定文化添加额外的资源文件,您需要这样做。

  1. 右键单击您ProjectSolution Explorer.
  2. 选择添加->新项目->资源 文件。
  3. 命名它Resources.en-us.resx。(用适当的代码替换“en-us”)
  4. 点击添加
  5. 将其拖到Properties文件夹中。
  6. 打开Resources.en-us.resx并将其更改Access ModifierPublic.
  7. 添加你的字符串。
  8. 对您需要支持的每种文化重复此操作。

在构建过程中,VS 会将.resx文件转换为.resource文件并为您构建包装类。然后您可以通过命名空间访问YourAssembly.Properties.Resources

有了这个 using 语句。

using YourAssembly.Properties;
Run Code Online (Sandbox Code Playgroud)

您可以使用以下属性进行装饰:

[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MyStringName")]
Run Code Online (Sandbox Code Playgroud)

注意:为了保持一致性,我使用了Properties文件夹。要使用 App_GlobalResources 将您的.resx文件移动到那里并更改您的 using 语句以匹配目录名称。像这样:

using YourAssembly.App_GlobalResources;
Run Code Online (Sandbox Code Playgroud)

编辑:最接近强类型资源名称的方法是执行以下操作:

public class ResourceNames
{
    public const string EmailRequired = "EmailRequired";
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用这样的属性进行装饰。

[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = ResourceNames.EmailRequired)]
Run Code Online (Sandbox Code Playgroud)

要启用自动客户端文化检测,请将全球化部分添加到web.config文件中。

<configuration>
    <system.web>
        <globalization enableClientBasedCulture="true" culture="auto:en-us" uiCulture="auto:en-us"/>
    </system.web>
<configuration>
Run Code Online (Sandbox Code Playgroud)

在这里,我启用了基于客户端的文化,并将文化uiculture 设置为“ auto ”,默认为“ en-us ”。


创建单独的卫星组件:

MSDN创建卫星程序集文章也会有所帮助。如果您不熟悉附属程序集,请务必阅读打包和部署资源

过去在创建附属程序集时,我发现使用 VS 构建事件很有用。这些是我将采取的步骤。

  1. Class Library在我的解决方案中创建一个单独的项目。
  2. 创建或添加我的.resx文件到这个项目。
  3. Post-Build EventProject Properties对话框中添加一个。(就像下面那个)

示例 VS 构建后脚本:

set RESGEN="C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\resgen.exe"
set LINKER="C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\al.exe"
set ASSEMBLY=$(TargetName)
set SOURCEDIR=$(ProjectDir)
Set OUTDIR=$(TargetDir)

REM Build Default Culture Resources (en)
%RESGEN% %SOURCEDIR%en\%ASSEMBLY%.en.resx  %SOURCEDIR%en\%ASSEMBLY%.resources

REM Embed Default Culture
%LINKER% /t:lib /embed:%SOURCEDIR%en\%ASSEMBLY%.resources /culture:en /out:%OUTDIR%%ASSEMBLY%.resources.dll
REM Embed English Culture
IF NOT EXIST %OUTDIR%en\ MKDIR $%OUTDIR%en\
%LINKER% /t:lib /embed:%SOURCEDIR%en\%ASSEMBLY%.resources /culture:en /out:%OUTDIR%en\%ASSEMBLY%.resources.dll


REM These are just a byproduct of using the project build event to run the resource build script
IF EXIST %OUTDIR%%ASSEMBLY%.dll DEL %OUTDIR%%ASSEMBLY%.dll
IF EXIST %OUTDIR%%ASSEMBLY%.pdb DEL %OUTDIR%%ASSEMBLY%.pdb
Run Code Online (Sandbox Code Playgroud)

如果您不想使用ResGen.exe来转换您的.resx文件,您可以执行以下操作。

using System;
using System.Collections;
using System.IO;
using System.Resources;

namespace ResXConverter
{
    public class ResxToResource
    {
        public void Convert(string resxPath, string resourcePath)
        {
            using (ResXResourceReader resxReader = new ResXResourceReader(resxPath))
            using (IResourceWriter resWriter = new ResourceWriter(
                    new FileStream(resourcePath, FileMode.Create, FileAccess.Write)))
            {
                foreach (DictionaryEntry entry in resxReader)
                {
                    resWriter.AddResource(entry.Key.ToString(), entry.Value);
                }
                resWriter.Generate();
                resWriter.Close();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以这种方式进行转换的潜在缺点之一是需要引用System.Windows.Forms.dll. 您仍然需要使用Assembly Linker

编辑:正如 wRAR 提醒我们的那样,如果您正在签署程序集,您的密钥必须匹配.


wRA*_*RAR 2

虽然这很奇怪,特别是对于熟悉开源本地化技术的人来说,但无法为任何系统程序集甚至第三方签名的系统程序集构建卫星程序集:

如果主程序集使用强命名,则附属程序集必须使用与主程序集相同的私钥进行签名。如果主程序集和附属程序集之间的公钥/私钥对不匹配,则不会加载您的资源。

是否可以自动实现相同的功能,但无需卫星组件,尚不清楚,但我对此表示怀疑。