Five New FxCop Globalization Rules

I have updated the downloadable source code for my .NET Internationalization book. The Visual Studio 2012 source code is downloadable from here. In this update there are 5 new FxCop globalization rules:-

  • Do not convert to uppercase - This rule catches all uses of ToUpper. It can be considered a more severe version of FxCop's own "Specify CultureInfo" rule. If the conversion to uppercase is used to perform a case insensitive comparison then String.Compare should be used instead. If the conversion to uppercase is used to change user data then it would be better not to convert the user data at all.
  • Do not convert to lowercase - This rule catches all uses of ToLower. It serves the same purpose as the previous rule except that it catches ToLower instead of ToUpper.
  • Boolean.ToString() is not localizable - This rule catches all uses of Boolean.ToString(). The words "True" and "False" are specific to English and are therefore not localizable. This rule is similar to the existing "Enum.ToString() is not localizable" rule.
  • Identifiers should not be called FirstName - This rule catches fields and properties that are called FirstName (or a variation of FirstName). The term "first name" is a western naming convention and it does not accurately identify a name part (even in Europe some countries use Family Name / Given Name order). Use the term "Given Name" instead.
  • Identifiers should not be called LastName - This rule catches fields and properties that are called LastName (or a variation of LastName). The term "last name" is a western naming convention and it does not accurately identify a name part. Use the term "Family Name" instead.

In total the downloadable source code now contains 25 FxCop globalization and localization rules.

Technorati Tags: ,,,

Currently rated 3.3 by 4 people

  • Currently 3.25/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Monday, April 22, 2013 at 6:04 PM
Tags:
Categories: Internationalization | .NET Internationalization Book
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed

A ResourceManager Abstraction for Custom Resource Managers

Please help me.

Of all of the features I would like added to the .NET Framework the top of the list is an abstraction from System.Resources.ResourceManager so that anyone could make use of Custom Resource Managers as an alternative to the .NET Framework's venerable .resx ResourceManager. It is relatively easy to add your own custom resource managers but what is more difficult is to ensure that those custom resource managers get used instead of System.Resources.ResourceManager.

So I am asking for your help. Microsoft reads and watches User Voice. In particular they pay attention to feature requests that get voted for. Please vote for Provide a ResourceManager abstraction mechanism and get this feature into the product.

Thank you.

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Monday, April 22, 2013 at 10:25 AM
Tags:
Categories: Internationalization
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Globalization: Know Your Enemy

I'm delighted to say that I will be delivering a new presentation at Gloucestershire .NET User Group on Wednesday 8th May 2013 and at DevTeach in Toronto on 28/29/30th May 2013. It is a presentation I have been wanting to put together for a few years but until recently I hadn't had the time. In the immortal words of Sun Tzu in The Art Of War 2500 years ago (translated from the original Chinese) "Know your enemy and know yourself and you can fight a thousand battles without disaster".

  • Globalization: Know Your Enemy
    Metaphorically speaking, the world is shrinking every day. Ironically this means that it is getting less acceptable to brush aside cultural differences and pretend that all cultures are essentially English but with different words. Appreciating globalization is about achieving humility, understanding that the world is a lot bigger than most developers give it credit for. Most developers understand that different cultures use different date formats, number formats and currencies. However, how many developers do not know that postal code formats, phone number formats, address formats and person name formats also differ. Not to mention the issues of localizing for gender-based languages or languages with less simplistic plural forms. What about ordinal subscripts, ordinal words, alphabet character sets ? The intention of this session is to open eyes, provide globalization enlightenment and with luck it will scare the living bejeezus out of you enough to make you question every line of code you write.

See you there.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Wednesday, March 13, 2013 at 2:36 PM
Tags:
Categories: Internationalization | Events
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (3) | Post RSSRSS comment feed

Announcing NCLDR (Alpha)

As from today you can download an alpha of NCLDR (see http://www.ncldr.com).

NCLDR is an open source port of CLDR to the .NET Framework. CLDR is the Common Locale Data Repository, a considerable database of culture data maintained by the Unicode Consortium and used by the rest of the non-Microsoft developer community. As such CLDR is analogous to the System.Globalization namespace in the .NET Framework with the difference that CLDR has nearly twice the number of cultures and has solutions for globalization and localization problems that the .NET Framework does not. NCLDR brings these cultures and these solutions to the .NET Framework.

There are a number of short videos on the NCLDR website that will help you get up to speed. The source code is on GitHub. There is also a NuGet package (search for pre-release packages).

Clearly this is an alpha release and it illustrates the potential of such a port but it isn't finished yet by a long way and I am looking for feedback of any kind on this project.

Enjoy.

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Monday, March 04, 2013 at 3:22 PM
Tags:
Categories: Internationalization | NCLDR
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Podcast: Interviewed by Jesse Liberty for Yet Another Podcast

I was recently interviewed by Jesse Liberty for Yet Another Podcast and you can listen to it at http://jesseliberty.com/2012/11/19/yet-another-podcast-82guy-smith-ferrier-on-internationalization/. The interview is 40 minutes long and is primarily about internationalization in .NET with a short discussion at the end on the .NET community in the UK. Along the way we discuss CLDR (the Common Locale Data Repository) and NCLDR (.NET CLDR), machine translation, how FxCop is one of the most misunderstood tools in the .NET world, pluralisation rules, genders, postcodes, currencies and more.

One point I would like to correct though: I make a point that the pluralisation rules for Polish (and Hungarian, Russian, Arabic and others) are more complex than for English. The actual rules that I quote are not quite right. For the record the Polish pluralisation rules are:-

  • Count: one, Rule: n is 1
  • Count: few, Rule: n mod 10 in 2..4 and n mod 100 not in 12..14
  • Count: many, Rule: n is not 1 and n mod 10 in 0..1 or n mod 10 in 5..9 or n mod 100 in 12..14
  • Other

Many thanks to Jesse Liberty for inviting me on the show - I really enjoyed talking about my favourite subject.

Currently rated 3.8 by 8 people

  • Currently 3.75/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Thursday, November 22, 2012 at 8:30 AM
Tags:
Categories: Internationalization
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Video: How To Achieve World(-Ready) Domination In ASP.NET MVC 4

The third aspConf (formerly mvcConf) was held on 17th and 18th July 2012. I was very pleased to present "How To Achieve World(-Ready) Domination In ASP.NET MVC 4" (aka "Internationalizing ASP.NET MVC"). You can watch a video of the presentation here. You can also download the slides and source code. Here's the session abstract:-

So you've written your ASP.NET MVC application and you want it to work in another language ? Then this session is for you. World-Readiness is all of the work that a developer needs to do to globalize an application and make it localizable (i.e. capable of being localized). In this session we will cover localizing HTML and HTML Helpers, localizing and globalizing Data Annotations, localizing and globalizing JavaScript and localizing URLs. No previous experience of ASP.NET localization is required.

Currently rated 3.6 by 7 people

  • Currently 3.571428/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Monday, August 27, 2012 at 4:50 PM
Tags:
Categories: Internationalization
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Add Satellite Assemblies To An Assembly For Any Culture

Since the very first release of the .NET Framework we have been able to build satellite assemblies for (almost) any culture. The critical factor though is that in order to do this either the original assembly must not have been signed or else you must be able to sign your satellite assembly with the same key. Clearly Microsoft will not give anyone the key they use to sign their assemblies so although Microsoft release various language versions of their products we, as consumers of those products, are unable to add our own language versions. This includes but is not limited to the .NET Framework itself, ASP.NET MVC and Silverlight.

I would like your help. I would like to optionally remove the restrictions on loading satellite assemblies. At present the satellite assembly must be signed with the same key as its parent assembly. I would like Microsoft to add a mechanism to the CLR which would optionally allow the author of the assembly to relax the rules on loading satellite assemblies such that it checks that the satellite assembly matches its parent in all criteria *except* for the key with which it is signed.

In this were possible then communities would be able to add support for their own language without waiting for Microsoft to support them. Close to home, this would mean that we could have a Welsh version of the .NET Framework (or ASP.NET MVC). This desire isn't limited solely to getting support for Welsh; the feature would work for all languages (there are ~7000 languages in the world and the .NET Framework 4 supports 23 of them so this affects a community near you).

So here's where I would like your help. If you think this is a useful feature please vote for it on User Voice here.

Thanks.

Currently rated 2.8 by 19 people

  • Currently 2.789474/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Tuesday, March 13, 2012 at 3:25 PM
Tags:
Categories: Internationalization
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

What's New In The .NET Internationalization Source Code

I wrote a book called .NET Internationalization back in 2006. There is a whole bunch of source code (examples and reusable library code) that accompanies the book that is available for download (you don't need to buy the book to get the source code). I have been keeping the source code up to date with various changes since it was first released and I have just uploaded the most recent version. This blog post describes what's new.

Custom Cultures

I added an example of a new custom culture for Spanish (Chile) Unidad de Fomento, es-CL-CLF, to support the UDF currency in Chile.

Resource Code Generators

I added 3 new code generators for Visual Studio:-

  • JavaScriptResourceCodeGenerator - Creates .js files (JavaScript object literals) from .resx files
  • JavaScriptAddParentsResourceCodeGenerator - Creates .js files (JavaScript object literals) from .resx files, adds all parents except invariant
  • JavaScriptAddAllParentsResourceCodeGenerator - Creates .js files (JavaScript object literals) from .resx files, adds all parents including invariant

Machine Translation

The PseudoTranslator has a new Boolean property, ExcludeMarkup (default is true), where characters that are markup tags (e.g. "<strong>") are not pseudo translated.

The GoogleTranslator is now deprecated because the Google v1 translation API was deprecated by Google in December 2010.

I added Google2Translator for the Google v2 translation API. This is a paid service. See http://code.google.com/apis/language/translate/v2/getting_started.html for details.

Resource Administrator

You can now specify a value for PseudoTranslationCultureInfoName in the App.Config which allows you to change the name of the culture used for pseudo translation.

The GoogleTranslator is no longer used.

The Google2Translator is used if a value for "Google2TranslatorApplicationKey" is set in the App.config file.

If either the MicrosoftTranslator or the Google2Translator are used the remaining translators are disabled (because the Microsoft and Google translators are very reliable).

I fixed a bug where comments were not being preserved in neutral and specific resources when automatic translation was on.

The FileBasedResourcesGovernor now has a new property, Extension, which is the file extension of the files (e.g. ".resx").

ResourceGovernor.ReintegrateResourceSet has various bugs fixed.

Globalization FxCop Rules

I added 2 new rules:-

  • DoNotConcatenateLocalizableStrings - identifies code where resource strings are concatenated (use string parameters instead)
  • ResourceEntryIsNotUsed - identifies properties in Strongly Typed Resource Classes that are not used

Note that the ResourceEntryIsNotUsed class requires the Strongly Typed Resource

Class code to be manually modified so that the CompilerGeneratedAttribute is commented out.

The Translator
I added two new utilities:-

  • ReintegrateResources - a command line utility that intelligently reintegrates resources being sent back from the translator
  • ResourcePackager - a command line utility that ZIPs and unZIPs .resx files being sent to/from the translator

Enjoy.

Technorati Tags: ,

Currently rated 3.1 by 9 people

  • Currently 3.111111/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Monday, March 12, 2012 at 4:19 PM
Tags:
Categories: .NET Internationalization Book | Internationalization
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed

Internationalizing ASP.NET MVC Around The UK

I will be presenting "Internationalizing ASP.NET MVC" (aka "How To Achieve World(-Ready) Domination In ASP.NET MVC") at the following venues over the next few months:-

Here's the session abstract:-

So you've written your ASP.NET MVC application and you want it to work in another language ? Then this session is for you. World-Readiness is all of the work that a developer needs to do to globalize an application and make it localizable (i.e. capable of being localized). In this session we will cover localizing HTML and HTML Helpers, localizing and globalizing Data Annotations, the importance of Resource Manager abstraction, localizing and globalizing JavaScript and localizing URLs. No previous experience of ASP.NET localization is required.

Do come along and bring your internationalization problems and questions. This is my favourite subject so getting me talking on it isn't difficult. It's getting me to shut up that's special.

Currently rated 3.8 by 8 people

  • Currently 3.75/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: guysmithferrier
Posted on: Tuesday, February 21, 2012 at 3:43 PM
Tags:
Categories: Internationalization | Events
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed

Building Localized XAP Resource Files For Silverlight 4

The steps for localizing Silverlight applications using standard .resx files are relatively straight forwards. You can follow these steps on my "Internationalizing Silverlight" slides and see a completed demo in the downloadable source code for the same presentation (see the Localization101 folder). The main problem to resolve in this scenario is that the strongly typed resource class must be public and must have a public constructor. The solution to this problem lies in a previous blog post. This blog post discusses the next stage.

Silverlight faces the same deployment problem that ClickOnce applications face: if you follow the regular localization route then your deployment solution includes all languages for all users. Purely for performance reasons this is not desirable. The optimum solution is to provide the user with only the resources for the one required language. There is no built-in solution in Visual Studio 2010 that covers this scenario - that is what this blog post is about.

The solution is to build one XAP file with the Silverlight application and fallback resources (e.g. SilverlightApplication1.xap) and a separate XAP containing language-specific satellite resource assemblies for each deployed culture (e.g. SilverlightApplication1.fr-FR.xap, SilverlightApplication.es-ES.xap). At runtime the Silverlight application dynamically loads the required XAP resource file. In earlier versions of Silverlight this was possible using WebClient to download the XAP file and AssemblyPart.Load to load the satellite resource assembly into the Silverlight application's domain. This is still possible but MEF (Managed Extensibility Framework) provides a much neater solution (MEF, however, performs almost exactly the same steps as the original solution). To load and use the XAP resource file change the App.Application_Startup event in App.xaml.cs to:-

private void Application_Startup(object sender, StartupEventArgs e)
{
    string xapResourceFilename = String.Format("{0}.{1}.xap",
        "SilverlightApplication1",
        Thread.CurrentThread.CurrentUICulture.Name);

    DeploymentCatalog catalog = new DeploymentCatalog(
        new Uri(xapResourceFilename, UriKind.Relative));

    CompositionHost.Initialize(catalog);

    catalog.DownloadCompleted += (s, args) =>
    {
        this.RootVisual = new MainPage();
    };

    catalog.DownloadAsync();
}

This code uses MEF's DeploymentCatalog to load the XAP resource file (e.g. SilverlightApplication1.fr-FR.xap) containing the application's satellite resource assembly (e.g. SilverlightApplication1.resources.dll). The new MainPage is only created once the download is complete (or has failed). At this point the satellite resource assembly has been loaded into the Silverlight application's app domain and the regular ResourceManager (or whatever resource manager class you use) can get to work resolving the resources. You can see a completed demo in the downloadable source code (see the DownloadOnDemand folder).

The hardest part to solve in this process is the creation of the XAP resource files (e.g. SilverlightApplication1.fr-FR.dll). There is no support for this scenario in Visual Studio 2010 so you have to build this bit yourself. Or rather, you have to download the MSBuild tasks that I have created to solve this problem. Silverlight.Build.Tasks.zip contains the source code to build a library of MSBuild tasks (Silverlight.Build.Tasks.dll) and an MSBuild targets file (Silverlight.Build.Tasks.targets) that you add to your Silverlight application's .csproj file. Full details are in the solution's ReadMe.txt but in essence you add the following lines to the bottom of your .csproj file:-

<Import Project="$(ProgramFiles)\MSBuild\I18N\Silverlight\v4.0\Silverlight.Build.Tasks.targets" />

<Target Name="AfterBuild" DependsOnTargets="XapResourcePackager">
</Target>

Then you add the following line immediately below your .csproj's </SupportedCultures> line:-

<PackageCultures>fr-FR</PackageCultures>

(where <PackageCultures> contains a comma delimited list of cultures to create XAP resource files for).

The result is that when you build your Silverlight application the necessary XAP resource files are also built. If your Silverlight application has a corresponding website that hosts the Silverlight application then those XAP files are copied to the website's ClientBin folder just like the Silverlight application's XAP. You can see a completed demo in the downloadable source code (see the DownloadOnDemandAutomatedBuild folder).

Of course this only covers one Silverlight deployment scenario but it is common enough that it demands a solution.

Enjoy.

Currently rated 3.4 by 13 people

  • Currently 3.384615/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: GuySmithFerrier
Posted on: Sunday, October 10, 2010 at 10:25 PM
Categories: Internationalization | Silverlight
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (4) | Post RSSRSS comment feed