2010-03-29 29 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); 
    } 
}