Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Phil Haack has an excellent article <em><a href="http://haacked.com/archive/2009/12/07/localizing-aspnetmvc-validation.aspx/" rel="nofollow noreferrer">Localizing ASP.Net MVC Validation</a></em> which specifically guides you through overriding your strings. This article applies more to <em><code>DataAnnotations</code></em> than it does <em><code>ASP.net MVC</code></em>. So, this will help however your are using <em>DataAnnotattions</em>.</p> <p>Below I have listed the simplest steps to add Localized Resources in Visual Studio.</p> <ol> <li>Open the <em><code>Project Properties</code></em> dialog.</li> <li>Select the <em><code>Resources</code></em> tab.</li> <li>Click to create a new <em>default resources file</em>.</li> <li>This will create two files in your <code>Properties</code> folder. <ul> <li><em>Resources.resx</em></li> <li><em>Resources.Designer.cs</em> </li> </ul></li> <li>When <em>Resources.resx</em> has opened, change it's <em><code>Access Modifier</code></em> to <em><code>Public</code></em>. </li> <li>Add your strings.</li> </ol> <p>To add additional <em>resource files</em> for <em>specific cultures</em> you will need to.</p> <ol> <li>Right click your <em><code>Project</code></em> in the <em><code>Solution Explorer</code></em>.</li> <li>Select <em>Add</em> -> <em>New Item</em> -> <em>Resource</em> File.</li> <li>Name it <em><code>Resources.en-us.resx</code></em>. (replace 'en-us' with appropriate code)</li> <li>Click Add</li> <li>Drag it into the <code>Properties</code> folder.</li> <li>Open <em>Resources.en-us.resx</em> and change it's <em><code>Access Modifier</code></em> to <em><code>Public</code></em>.</li> <li>Add your strings.</li> <li>Repeat for each Culture you need to support.</li> </ol> <p>During the build VS will convert the <em>.resx</em> files to <em>.resource</em> files and build wrapper classes for you. You can then access via the namespace <em><code>YourAssembly.Properties.Resources</code></em>.</p> <p>With this using statement.</p> <pre><code>using YourAssembly.Properties; </code></pre> <p>You can decorate with attributes like this:</p> <pre><code>[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MyStringName")] </code></pre> <p>Note: I used the <em>Properties</em> folder for consistency. To use the App_GlobalResources move your <em>.resx</em> files there and change your using statement to match the directory name. Like this:</p> <pre><code>using YourAssembly.App_GlobalResources; </code></pre> <hr> <p>Edit: The closest that you can get to Strongly Typed resource names would be to do something like this:</p> <pre><code>public class ResourceNames { public const string EmailRequired = "EmailRequired"; } </code></pre> <p>You can then decorate with attributes like this.</p> <pre><code>[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = ResourceNames.EmailRequired)] </code></pre> <p>To enable automatic client culture detection add the <em><a href="http://msdn.microsoft.com/en-us/library/ey4b4s95.aspx" rel="nofollow noreferrer">globalizationsection</a></em> to the <em>web.config</em> file. </p> <pre><code>&lt;configuration&gt; &lt;system.web&gt; &lt;globalization enableClientBasedCulture="true" culture="auto:en-us" uiCulture="auto:en-us"/&gt; &lt;/system.web&gt; &lt;configuration&gt; </code></pre> <p>Here I have enabled a client based culture and set the <em>culture</em> and the <em>uiculture</em> to "<em>auto</em>" with a default of "<em>en-us</em>".</p> <hr> <p>Creating Separate Satellite Assemblies:</p> <p>The MSDN <em><a href="http://msdn.microsoft.com/en-us/library/21a15yht.aspx" rel="nofollow noreferrer">Creating Satellite Assemblies</a></em> article will help as well. If you are new to satellite assemblies make sure you read <em><a href="http://msdn.microsoft.com/en-us/library/sb6a8618.aspx" rel="nofollow noreferrer">Packaging and Deploying Resources</a></em>.</p> <p>When creating satellite assemblies in the past, I have found it useful to use VS build events. These are the steps I would take.</p> <ol> <li>Create a separate <em><code>Class Library</code></em> project in my solution.</li> <li>Create or Add my <em><code>.resx</code></em> files to this project.</li> <li>Add a <em><code>Post-Build Event</code></em> to the <em><code>Project Properties</code></em> dialog. (Like the one below)</li> </ol> <p>Sample VS Post-Build Script:</p> <pre><code>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 </code></pre> <p>If you would prefer not to use <em><a href="http://msdn.microsoft.com/en-us/library/ccec7sz1.aspx" rel="nofollow noreferrer">ResGen.exe</a></em> to convert your <em><code>.resx</code></em> files, you could do something like this.</p> <pre><code>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(); } } } } </code></pre> <p>One of the potential draw backs to doing the conversion this way is the need to reference the <code>System.Windows.Forms.dll</code>. You will still need to use <em><a href="http://msdn.microsoft.com/en-us/library/c405shex.aspx" rel="nofollow noreferrer">Assembly Linker</a></em>.</p> <p>Edit: As wRAR has reminded us if you are signing your assemblies your keys <a href="http://msdn.microsoft.com/en-us/library/ff8dk041.aspx" rel="nofollow noreferrer">must match</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload