我想覆盖来自ASP.NET项目的System.ComponentModel.DataAnnotations
的字符串。我是否需要制作附属程序集,搞乱自定义构建任务,al.exe
等?即使是,我也找不到如何将.resx
转换为.resources
并将其提供给al.exe
的方法。如果没有,则将.resx.
放在哪里以及如何命名?
UPD:明确地说:我想使用自定义资源字符串,而不是程序集中默认资源中的一个。我不想在使用该字符串的每个位置进行更改。毕竟,存在资源只是为了覆盖它们。
最佳答案
Phil Haack的精彩文章Localizing ASP.Net MVC Validation专门指导您覆盖字符串。与DataAnnotations
相比,本文更适用于ASP.net MVC
。因此,这将有助于您使用DataAnnotattions。
下面,我列出了在Visual Studio中添加本地化资源的最简单步骤。
Project Properties
对话框。 Resources
选项卡。 资源文件。
Properties
文件夹中创建两个文件。打开,将其更改为
Access Modifier
到Public
。 要为特定区域性添加其他资源文件,您将需要。
Project
。 文件。
Solution Explorer
。(将“en-us”替换为适当的
代码)
Resources.en-us.resx
文件夹中。 Properties
到Access Modifier
。 支持。
在构建过程中,VS会将.resx文件转换为.resource文件,并为您构建包装器类。然后,您可以通过 namespace
Public
进行访问。有了这个using语句。
using YourAssembly.Properties;
您可以使用以下属性进行修饰:
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MyStringName")]
注意:我使用Properties文件夹是为了保持一致性。要使用App_GlobalResources,请将您的.resx文件移动到此处,并更改using语句以匹配目录名称。像这样:
using YourAssembly.App_GlobalResources;
编辑:可以最接近强类型资源名称的方法是执行以下操作:
public class ResourceNames
{
public const string EmailRequired = "EmailRequired";
}
然后,您可以使用这样的属性进行修饰。
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = ResourceNames.EmailRequired)]
要启用自动客户端区域性检测,请将globalizationsection添加到web.config文件中。
<configuration>
<system.web>
<globalization enableClientBasedCulture="true" culture="auto:en-us" uiCulture="auto:en-us"/>
</system.web>
<configuration>
在这里,我启用了基于客户端的文化,并将文化和uiculture设置为“自动”,默认设置为“en-us”。
创建单独的附属程序集:
MSDN Creating Satellite Assemblies文章也会有所帮助。
如果您不熟悉卫星装配,请确保您阅读Packaging and Deploying Resources。
过去创建附属程序集时,我发现使用VS构建事件很有用。这些是我要采取的步骤。
YourAssembly.Properties.Resources
项目。 Class Library
文件到该项目。 .resx
添加到Post-Build Event
对话框。 (就像下面的一样)样本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
如果您不想使用ResGen.exe转换
Project Properties
文件,则可以执行以下操作。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();
}
}
}
}
用这种方法进行转换的潜在缺点之一是需要引用
.resx
。您仍然需要使用Assembly Linker。编辑:正如wRAR提醒我们的那样,如果您正在对程序集进行签名,则 key 为must match。