2010-03-29 75 views
5

我想覆盖System.ComponentModel.DataAnnotations中ASP.NET项目的字符串。我是否需要制作卫星组件,搞乱定制构建任务,al.exe等?即使是的话,我也找不到如何将.resx转换为.resources来将它传送到al.exe。如果没有,那么.resx.的位置以及如何命名?在ASP.NET中覆盖标准程序集中的资源

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

回答

2

虽然这是奇怪的,尤其是对于熟悉开源定位技术的人,一个不能建立一个卫星组装任何系统的组装,甚至是第三方签订一个:

If your main assembly uses strong naming, satellite assemblies must be signed with the same private key as the main assembly. If the public/private key pair does not match between the main and satellite assemblies, your resources will not be loaded.

是否有可能自动,但没有卫星组装,是未知的,但我怀疑这一点。

1

假设要覆盖在验证属性默认错误消息字符串,你可以做,通过设置这样的ErrorMessageResourceNameErrorMessageResourceType属性:

[Required(ErrorMessageResourceName = "Required_Username", ErrorMessageResourceType = typeof(MyResourceFile)] 
public string Username { get; set; } 

可以创建名为MyResourceFile资源文件.resx包含Required_Username与您想要的错误消息。

希望这会有所帮助。

+0

我知道这一点,但我不想更改所有属性。 – wRAR 2010-04-05 08:49:21

4

菲尔哈克有一篇很好的文章Localizing ASP.Net MVC Validation它专门引导你通过重写你的字符串。本文适用更DataAnnotations比它ASP.net MVC。因此,这将有助于您使用DataAnnotattions

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

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

要为你需要特定文化添加额外资源文件

  1. 右键点击您在 Solution ExplorerProject
  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 YourAssembly.Properties; 

你可以用这样的属性修饰:

[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MyStringName")] 

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

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构建事件很有用。这些是我会采取的步骤。

  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 

如果你不希望使用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(); 
      } 
     } 
    } 
} 

一个潜在的抽奖背上来执行转换这种方式是引用System.Windows.Forms.dll的需要。您仍然需要使用Assembly Linker

编辑:由于wRAR提醒我们您是否在签署装配您的钥匙must match

+0

我已阅读所有这些链接。第一个链接建议明确地将资源名称放在属性中,这不是我想要的。至于卫星程序集,我仍然无法理解(甚至在MSDN中找到相关位置)应如何命名程序集,名称空间和资源以由运行时加载以及是否存在其他要求。 System.ComponentModel.DataAnnotations.resources.dll包含System.ComponentModel.DataAnnotations.resources 或System.ComponentModel.DataAnnotations.Resources.DataAnnotationsResources.resources明显未加载。 – wRAR 2010-04-05 17:05:22

+0

@wRAR:在我们开始命名约定之前,您是否想要在运行时指定显示的消息类型,还是不想在属性中使用字符串? – VoidDweller 2010-04-05 17:45:26

+0

我只想本地化标准字符串。 – wRAR 2010-04-05 17:48:08

0

如果服务器没有安装.NET语言包,那么无论CurrentUICulture设置为什么,您都将在DataAnnotations验证消息中获得英语。这史诗般的黑客为我们工作。

  • 转到 “的Microsoft .NET Framework 4.6.1语言包” 下载页面https://www.microsoft.com/en-us/download/details.aspx?id=49977
  • 选择语言,并下载
  • 提取NDP461-KB3102436-x86的x64的AllOS- {} LANG .EXE 7 -Zip
  • 与7-Zip的
  • 提取CAB文件x64-Windows10.0-KB3102502-x64.cab
  • 找到 “msil_system.componentmod..notations.resources _....”
  • ...在你会发现“system.componentmodel.dataannotations.resources.dll”
  • 与ILSpy打开.resources.dll,找到资源,然后点击上面的字符串表保存按钮为System.ComponentModel.DataAnnotations.Resources.DataAnnotationsResources。{语言}的.resources
  • 添加到您的项目在说一个“资源“
  • 确保文件构建资源文件设置为Action属性‘嵌入的资源’

然后在你的项目的预启动方法,你覆盖System.ComponentModel.DataAnnotations.Resources.DataAnnotationsResources.resourceMan私有静态字段(告诉你这是一个黑客)与你在你的项目中拥有的一样。

using System; 
using System.Linq; 
using System.Reflection; 
using System.Resources; 

[assembly: WebActivator.PreApplicationStartMethod(typeof(ResourceManagerUtil), nameof(ResourceManagerUtil.PreStart))] 

class ResourceManagerUtil 
{ 
    public static void PreStart() 
    { 
     initDataAnnotationsResourceManager(); 
    } 

    /// <summary> 
    /// If the server doesn't have .NET language packs installed then no matter what CurrentUICulture is set to, you'll always get English in 
    /// DataAnnotations validation messages. Here we override DataAnnotationsResources to use a ResourceManager that uses language .resources 
    /// files embedded in this assembly. 
    /// </summary> 
    static void initDataAnnotationsResourceManager() 
    { 
     var embeddedResourceNamespace = "<YourProjectDefaultNamespace>.<FolderYouSavedResourcesFilesIn>"; 
     var dataAnnotationsResourcesName = "System.ComponentModel.DataAnnotations.Resources.DataAnnotationsResources"; 
     var thisAssembly = typeof(ResourceManagerUtil).Assembly; 
     var dataAnnotationsAssembly = typeof(System.ComponentModel.DataAnnotations.ValidationAttribute).Assembly; 

     var resourceManager = new ResourceManager(embeddedResourceNamespace + "." + dataAnnotationsResourcesName, thisAssembly); 

     // Set internal field `DataAnnotationsResources.resourceMan` 
     var dataAnnotationsResourcesType = dataAnnotationsAssembly.GetType(dataAnnotationsResourcesName); 
     var resmanProp = dataAnnotationsResourcesType.GetField("resourceMan", BindingFlags.NonPublic | BindingFlags.Static); 
     resmanProp.SetValue(null, resourceManager); 
    } 
}