AJ's blog

November 23, 2014

WCF Policy – Part 1: What is policy about?

Filed under: .NET, .NET Framework, SOA, Software Architecture, Software Development, WCF — ajdotnet @ 3:16 pm

Remember what I described during the introduction? Switch a feature on on the server, and the WCF takes care that this information gets pushed through to the client, at runtime client and server work together to fulfill the demand, and on top of it the developer can interfere if necessary.

Add the tiny fact that the “feature” in question usually adheres to some standard, and you have a policy and its implementation – in our case a “WCF Policy”. Let’s look into this a little more in detail, as this defines our to-do-list for the upcoming posts.

Note: This post is part of a series. The TOC can be found here

Policy explained…

The world of services is based on various standards. These standards provide the set of features to choose from. Defining how a standard is employed by a particular service is actually defining the policy for said service.

Now, bringing this – so far abstract – concept of a policy to live in WCF includes several aspects:

  • Initially the developer needs some way to activate the feature on the service (or – rarely – the client), i.e. to switch it on and configure the details.
  • At design time the policy has to be advertised by the service. The most basic aspects like transport protocol and message format are already addressed in the WSDL and XSD. For everything that goes beyond that we have WS-Policy. On the server the information needs to be put into the WSDL, on the client it needs to be evaluated to generate a respective client proxy.
  • At runtime the policy has to be implemented by some runtime component; again, client and server.
  • Additionally, information implied by the policy should be accessible by the developer. Depending on the actual demand, this may be informal, he may be able to interfere, ore he may actually be required to provide additional input. (Say the username and password for basic authentication.)


OK, let’s make this a little more tangible and have a look at how it applies to employing WS-Addressing in WCF. This will also define the to-do-list for our own custom policy…

Initially the developer needs to declare that his service uses WS-Addressing. WCF covers WS-Addressing through different bindings. WsHttpBinding does it implicitly, a custom binding configures SOAP and WS-Addressing versions as part of the message encoding:

The binding also takes care of advertising the policy in the WSDL. Since WSDL itself has no knowledge of WS-Addressing, WS-Policy comes into play. WS-Policy is by itself a rather dull standard. It merely defines how to place additional information (particularly for the use of policies) in the WSDL. In our case it might look like this:

The element wsaw:UsingAddressing is called a custom policy assertion provided by WS-Addressing – Metadata – in general an arbitrary XML fragment. WS-Policy also provides means to define combinations and alternatives between policy assertions.

WCF also addresses the client side by generating a client proxy from a respective WSDL. This process includes handling policy assertions and generating the respective configuration (e.g. by choosing the appropriate binding) or code.

At runtime the actual behavior kicks in: The WCF client automatically generates a message ID for the SOAP request and includes it in the message as SOAP header:

The server takes the message ID and includes it in the reply message using the RelatesTo SOAP header.

Additionally the developer can access the message ID on the server and manipulate it, as he likes.


To summarize this, here’s what makes up a policy in WCF:

During design:

  • Definition of the underlying standard

During development:

  • A way to switch the policy on and to configure as necessary
  • Advertising the policy in the WSDL
  • Evaluating the policy assertion during client proxy generation

During runtime:

  • Establishing the default behavior on server and client
  • Providing an interface to the developer

And this defines what we’re going to have to do – in the following posts…


That’s all for now folks,

Building Your Own Policy with WCF

Filed under: .NET, .NET Framework, C#, SOA, Software Architecture, Software Development, WCF — ajdotnet @ 2:55 pm

Flexibility and extensibility of WCF is really great. You need a feature provided by the platform? Just switch it on, via code or configuration, and all the bits and pieces follow suit. The fact is advertised in the WSDL; the client proxy generation will pick that up and produce respective code and configuration; both, client and server, do their part to make it work at runtime; and last not least the developer usually gets the means to access or manipulate the respective information, should the need arise.

Wouldn’t it be nice to have the same apply to your custom demands, demands not covered by the platform? Demands like…

  • New versions of standards you need to support, but which are not supported by the platform yet.
  • Homegrown authentication schemes.
  • Tenants for multi-tenant solutions.
  • Billing information for services in B2C scenarios.
  • SLA and diagnostics information for operations

Whatever the reason, it would be very nice if we could implement our custom policy in a way that the application developer could use it in a way very similar to policies provided by the platform.

The good news is: It is actually possible to support custom demands in a way very similar to the built-in features of WCF.
The not-so-good news: It is not that simple or straight-forward to do, as there a a lot of bits and pieces working together – and no single information source putting them together. Well, this is what I’m trying to accomplish…

So, here’s the agenda for this little adventure:

Design time aspects:

Runtime aspects:

Looking back:

Quite a bit more than one post…

So stay tuned…

That’s all for now folks,

April 19, 2014

ASP.NET MVC I18n – Part 10: Finish

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 4:09 pm

This is it. The complete overview of localizing a regular MVC based web application.

Here’s what we covered in this series, shown in context. The image contains links to the respective posts:

Quite some content for a rather common demand…


….and still, there’s some ground I did not cover:


This is the one thing regarding localization I avoided. The reason is simple: I don‘t know enough about this topic.

Technically there is the dir attribute in HTML and a respective direction property in CSS. But beyond that I would also want to know how RTL affects the screen layout, tab order, etc..


Not much to say. WebAPI controllers participate in the scheme we have set up, so the controller is aware what culture the user prefers. The data serialization itself ignores the culture, thus data exchange at the raw level (JSON) is not even affected.

Client side localization.

Apart from a few hints regarding client side validation (which is specifically supported by MVC via unobtrusive validation), everything I presented basically happened on the server.

So, if you build your application using Knockout, Angular, Sencha, or other frameworks – which generate large chunks of the UI employing databinding strategies – you will need to localize on the client as well. The server may still provide the necessary backing in terms of logic and translations e.g. as JSON service.

And JavaScript itself is still evolving.

“App” development.

Taking „client side“ one step further and building container applications based on PhoneGrap/Cordova, you will have to provide everything on the client; you just cannot afford to not render the UI just because the device has no connection right now. Thus you’ll need to address localization completely on the client, functionality as well as information; no server backing in this case, sorry.

Data localization.

For an application used internationally, it may not be sufficient to just localize the UI. You may have to localize your actual data. Formats, content, even business rules.

This may include providing downloadable content in different languages. (That exposé just became a collection, rather than a single file.) Take the different naming schemes into account. International addresses? Have fun. Types of business entities. Currencies, calendars, other units of measurement. (Thank god, we‘re talking about business applications; historians have to deal with the really funny stuff… . (Some people actually think IBAN and BIC are simple… .)


Well, I’m going to leave these topics for someone else. And with that, I conclude this little series. You can find the sources of the sample I built for this series on github (VS2013 project, NuGet packages have to be restored using “Enable NuGet Package Restore”, IIS Express is expected).


That’s all for now folks,

February 1, 2014

ASP.NET MVC I18n – Part 9: 3rd Party Controls

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — Tags: — ajdotnet @ 4:48 pm

Localization quite regularly involves localizing additional 3rd party controls. This is something that your control has – obviously – to support. Fortunately many controls – certainly the commercial ones, such as Telerik do. Unfortunately (but not unexpectedly) each and every one has its own approach to localization.

Note: This post is part of a series

To get a better feeling for the demands, let’s take a look at the jQuery UI date picker – the canonical example for additional controls.

Using the date picker is relatively simple: It typically is already included in an MVC project, the respective bundles for script and CSS files are readily defined and only need to be included in the _layout.cshtml. That done, a little initialization script (datepicker.initialize.js) will turn a textbox into a date picker:

$(document).ready(function () {
    var lang = $("html").attr("lang");

This script needs to be included in our views which can be achieved with minimal impact by including it in the existing UI bundle:

var bundle = bundles.GetBundleFor("~/bundles/jqueryui");

And the result works as expected…

… using American localization.



In order to localize the date picker, you need respective localization files. You can either grab them all (quite simple using the nuget package jQuery.UI.i18n), or you can grab the ones you actually need from github. Using these files, again, causes minimal impact if you simple include them in the bundle as above:

var bundle = bundles.GetBundleFor("~/bundles/jqueryui");
    "~/Scripts/jquery-ui-i18n.js", // option 1: from nuget package
    //"~/Scripts/jquery.ui.datepicker-*", // option 2: single localization files


Including the localization scripts will not only register the necessary information, it will actually switch the default language for the date picker. So, if you grabbed the file using nuget, you will end up with Chinese (zh-TW) as date picker region…

With single files, you might include just the one that is actually needed, and avoid that issue. Only you can’t use the nuget package in this cases, as it contains one single script file with all localizations. In any case you could provide your own initialization, that comes after those scripts and sets the date picker region to the correct one, by adjusting the initialization script above:

var lang = $(„html“).attr(„lang“);

We have all the information handy and did the same thing for globalize, right?

Wrong actually. Date picker localizations generally exist for the neutral culture (e.g. de) and only those specific cultures that differ form the default one. E.g. there is a localized version for en-GB, but not en-US, or de-DE respectively, as en and de are sufficient. On top of that the date picker does not support a proper fallback strategy, i.e. setting the region to de-DE will end up using the last included region, again zh-TW if you included all regions, not de.

This is an issue that is rarely mentioned and sometimes missed completely.

The solution is a mapping from our application‘s supported regions to regions supported by the date picker. You could do this on the server and provide a second attribute (e.g. langDatePicker) beside lang on the html tag. If you grabbed single localization files for the date picker, you could automate this by just scanning the available .js files. Or – for just two regions probably the more sensible approach – just do it in the initialization script:

$(document).ready(function () {
    var lang = $("html").attr("lang");
    if (lang == "de-DE")
        $.datepicker.setDefaults($.datepicker.regional[""]); // en-US is default

And now the date picker changes formats, appearance (e.g. first day of the week), etc.:



Localizing the date picker control can e done completely in all aspects. But there are also some inconsistencies compared to localizing the validation:

  • The globalize nuget package comes with single files, the date picker nuget package provides one consolidated file. This makes it harder to include just the one localization needed. (Performance is hardly an argument, as this is addressed by the bundle logic anyway.)
  • With Globalize you need to set a region explicitly, the date picker does it implicitly with referencing the localization file.
  • Globalize supports a fallback to the neutral culture if the specific region is not available. Date picker does nothing of the kind and simply ignores the call.

And these are the subtle differences in two packages from the jQuery universe. That might be a good indicator as to what to expect with 3rd party libraries from another source. Bring together a couple of controls, and you’ll have a mighty mishmash.


That’s all for now folks,

January 25, 2014

ASP.NET MVC I18n – Part 8: Data Validation

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 3:13 pm

The last post showed how to display localized validation error messages. Time to be able to actually validate ;-)

Note: This post is part of a series

This is another topic that is widely documented for the most part, but has some notable gaps.

Remember the error from last post:

Having the error message in localized German does not solve the fact that the date is actually in the valid local format in the first place. We should not even get an error.

The basic problem is that jQuery validation uses regular JavaScript methods to do validation, thus some valid data, if in localized format, will produce validation errors. But even worse is the fact that some data validates just fine – but with a wrong value. E.g. point and comma in numeric values switch their meaning from en-US to de-DE, similarly day and month change their position between en-US and fr-FR.

The generally cited answer to solve this issue is to use Globalize from github… which requires a little handiwork.



… you need to grab the globalize.js file from github under lib\ as well as the necessary localizations under lib\cultures\. If you require compressed versions (globalize.min.js below), you’ll have to create them yourself, e.g using http://jscompress.com/, as they are not provided. All files are then placed in the /Scripts folder of your web project.

Note: there is also a nuget package, which will install these files – including all localizations, but still no minified version.



… the scripts need to be included in our views. There are two options, which can both be found:

A) Define a respective bundle…

bundles.Add(new ScriptBundle("~/bundles/globalization")

and render it in _layout.cshtml – before the „script“ section is rendered, because that is where validation will come into play:

@RenderSection("scripts", required: false)

B) Instead of including all localization files (i.e. the globalize.culture.*.js files) you could also just include the necessary one. In that case it’s probably simpler to go without bundle:

@Scripts.Render("~/Scripts/globalize.culture." + Culture + ".js")



… we need to initialize the culture on the client side.

For this a call to Globalize.culture is necessary. You could generate the respective call an the server, passing in the current UI culture – which is what you’ll see very often in tutorials. However the information is already available on the client (because we put it there), thus a static script globalize.initialize.js will do (and will benefit http caching):

$(document).ready(function () {
    // use the language provided from server…
    var lang = $("html").attr("lang"); 
    if (typeof Globalize != ‘undefined’)



…we need some plumbing.

We have the necessary infrastructure for localization, but jQuery validation does not use it yet. The final step is to wire jQuere validation with the new globalize methods. This is something that everyone has to do. Something that is quite simple. Something that could have been provided. Something that someone could have told you how to do. Guess what? Nobody did. [UPDATE: Turns out, I was wrong, see below. I still kept the following content for the explanations.]

jQuery has an object that provides the necessary validation methods: $.validator.methods. All that is necessary is to reroute them to replacements that make use of the globalization library. For MVC and unobtrusive validation, that requires just 5 methods: number, date, min, max, and range. In yet another additional script file globalize.validation.js:

// replace methods in jquery.validate.js ($.validator.methods) as necessary for localized validation:

$.validator.methods.number = function (value, element) {
    return this.optional(element) || !isNaN(Globalize.parseFloat(value));

$.validator.methods.date = function (value, element) {
    if (this.optional(element))
        return true;
    var result = Globalize.parseDate(value);
    return !isNaN(result) && (result != null);

$.validator.methods.min = function( value, element, param ) {
    return this.optional(element) || Globalize.parseFloat(value) >= param;

$.validator.methods.max = function( value, element, param ) {
    return this.optional(element) || Globalize.parseFloat(value) <= param;

$.validator.methods.range = function (value, element, param) {
    if (this.optional(element))
        return true;
    var result = Globalize.parseFloat(value);
    return (result >= param[0] && result <= param[1]);

Note: If you are using jQuery validation directly (not via unobtrusive validation), you’ll need to wire all methods in $.validator.methods respectively.

What‘s left is including this script in a bundle. Since there is already a bundle associated with validation and included in respective edit views, I just extended it:

var bundle = bundles.GetBundleFor("~/bundles/jqueryval");


And now our validation code works just fine, properly recognizing German date and number formats.

UPDATE: Just when I finished writing this post, I stumbled upon John‘s post, which is the first one I found that connects Globalize and jQuery validation both correctly and completely, and even provides a nuget package.


That’s all for now folks,

January 19, 2014

ASP.NET MVC I18n – Part 7: Model Attributes

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 5:19 pm

The last post introduced resources and used them directly. When it comes to localizing views aspects based on data – i.e. databinding against models – resources are also the means to localize the data aspects.

Note: This post is part of a series

Localizing the displayed data is something that is fairly broadly documented, therefore I can keep the basics to the minimum and focus on the stuff that is rarely mentioned. If you need more background, the ASP.NET site provides the perfect starting point.

This post will concentrate on localizing the data related labels and validation messages; localizing the actual validation is going to be addressed in the next post.


The M-part in MVC is the model, in ASP.NET MVC usually consisting of POCOs. Data validation as well as localizing labels in MVC is based on attributes put on the data model. The very first question – and usually one that is not addressed – is one more related to architecture than to plain code: Which class shall I attribute?

Remember the contract data model that I introduced in the initial post:

namespace MyStocks.BusinessContract
    [DebuggerDisplay("BusinessContract.Stock: {ID} {Isin} {Name} {Price} {Date}")]
    public class Stock
        public int ID { get; set; }
        /// <summary>
        /// http://en.wikipedia.org/wiki/International_Securities_Identification_Number
        /// 12-character alpha-numerical code
        /// </summary>
        public string Isin { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public DateTime Date { get; set; }

Technically, we could just put attributes on this contract data model. However, that would result in UI-specific information bleeding into the business contract. (I elaborated on this topic in an earlier post.) So, to make it short, do NOT put view related attributes on those classes. Instead provide model classes intended for the presentation layer. For our little example the contract class is just copied to the model folder of our MVC project, but in my experience models in ASP.NET MVC have a tendency to become view related models (to avoid the term viewmodel) with the actual data just being one aspect. Now we can apply the necessary validation attributes:

[DebuggerDisplay("Models.Stock: {ID} {Isin} {Name} {Price} {Date}")]
public class Stock
    public int ID { get; set; }
    public string Isin { get; set; }
    public string Name { get; set; }
    [DisplayFormat(DataFormatString = "{0:f2}")] // currency would include currency sign
    public decimal Price { get; set; }
    public DateTime Date { get; set; }

This of course requires mapping the data back and forth. For more complex applications you might consider something like AutoMapper for this task, but in simple cases plain code will do:

using ContractStock = MyStocks.BusinessContract.Stock; // business contract model
using ModelStock = MyStocks.Mvc.Models.Stock; // mvc model

namespace MyStocks.Mvc.Models
    static class Mapper
        public static ModelStock MapToUI(this ContractStock stock)
            return new ModelStock
                Date = stock.Date,
                ID = stock.ID,
                Isin = stock.Isin,
                Name = stock.Name,
                Price = stock.Price
        public static ContractStock MapToContract(this ModelStock stock)
            return new ContractStock
                Date = stock.Date,
                ID = stock.ID,
                Isin = stock.Isin,
                Name = stock.Name,
                Price = stock.Price

And call these methods as appropriate in the controller:

public class StockController : Controller
    protected MyStocks.BusinessContract.IStockService StockService { get; set; }
    public StockController()
        this.StockService = new MyStocks.BusinessService.StockService();
    // GET: /Stock/
    public ActionResult Index()
        var model = StockService.GetAllStocks().Select(Mapper.MapToUI);
        return View(model);

(Of course, in a real-word application this is the place to employ DI, e.g. Unity.)

The (mostly generated) view picks the information up using extension methods:

@model IEnumerable<MyStocks.Mvc.Models.Stock>
 ViewBag.Title = Labels.Navigation_Stock_Index;
        <th>@Html.DisplayNameFor(model => model.Isin)</th>
        <th>@Html.DisplayNameFor(model => model.Name)</th>
        <th>@Html.DisplayNameFor(model => model.Price)</th>
        <th>@Html.DisplayNameFor(model => model.Date)</th>
    @foreach (var item in Model)
            <td>@Html.ActionLink(item.Isin, "Details", new { id = item.ID })</td>
            <td>@Html.DisplayFor(modelItem => item.Name)</td>
            <td style="text-align:right">@Html.DisplayFor(modelItem => item.Price) </td>
            <td>@Html.DisplayFor(modelItem => item.Date)</td>
<br />
<br />
@Html.ActionLink(Labels.Navigation_Back, "Index", "Home")

If you run the application, the usual outcome is something like this:

As you can see, property names are used for field labels. Jumping to details and edit view, we will also get validation messages based on our attributes from above:

You might already see the respective validation messages properly translated. This depends on the language version of the installed .NET Framework. Generally I would be careful to rely on the fact that all necessary languages are installed in production. Latest when custom feedback is required you need to provide the message in any case.

Providing localized validation messages, as well as display names for labels, can be done providing the „link“ to the respective resources, using attributes in the MVC model. DisplayAttribute for the display name, and the validation attributes for respective error messages:

[DebuggerDisplay("Models.Stock: {ID} {Isin} {Name} {Price} {Date}")]
public class Stock
    public int ID { get; set; }
    [Required(ErrorMessageResourceType = typeof(Localizations.Models), ErrorMessageResourceName = "Validation_Required")]
    [RegularExpression(@"[a-zA-Z]{2}[\w]{9}[\d]{1}", ErrorMessageResourceType = typeof(Localizations.Models), ErrorMessageResourceName = "Stock_Isin_RegEx")]
    [Display(ResourceType = typeof(Localizations.Models), Name = "Stock_Isin")]
    public string Isin { get; set; }
    [Required(ErrorMessageResourceType = typeof(Localizations.Models), ErrorMessageResourceName = "Validation_Required")]
    [Display(ResourceType = typeof(Localizations.Models), Name = "Stock_Name")]
    public string Name { get; set; }
    [Required(ErrorMessageResourceType = typeof(Localizations.Models), ErrorMessageResourceName = "Validation_Required")]
    [Display(ResourceType = typeof(Localizations.Models), Name = "Stock_Price")]
    [DisplayFormat(DataFormatString = "{0:f2}")] // currency would include currency sign
    public decimal Price { get; set; }
    [Required(ErrorMessageResourceType = typeof(Localizations.Models), ErrorMessageResourceName = "Validation_Required")]
    [Display(ResourceType = typeof(Localizations.Models), Name = "Stock_Date")]
    public DateTime Date { get; set; }

That much can be found in any tutorial. What is also rarely mentioned though (much less documented), is that these localized messages can use string.Format placeholders. Let’s state that clearly: You do not have to provide „field XY is required“ messages for each and every field! (as some posts imply…).

All validation attributes support at least a placeholder for the field name, most also their additional parameters, such as the length in MinLengthAttribute. In other words, those resources would be sufficient for all respective fields:

Validation_Required= „{0} is a required field!“
Validation_MaxLength= „{0} must be shorter or equal to {1} characters!“

BTW: In case you do not like to clutter your source with all these addition parameters in your attributes, Phil uses the MVC infrastructure to resolve and inject localized messages using a convention based approach.


Once this is done, we get localized validation messages – with one final hole to patch: Look at all those nicely localized labels and messages… and the one culprit refusing to cooperate, the error message on the date (“Datum”) field:

The reason this does not work is that this message does not come from validation, but from binding. Binding is what turns the text into the appropriate data type (which implies „syntactic correctness“), while semantic validation checks the resulting value against some rules. See here for background.

The immediate consequence is that localization is done differently. Actually there are only two possible cases, numbers and dates, and there is only one way to supply them:

  • Define a resource file in App_GlobalResources – yes, I said, don‘t use it. This is the exception that proves the rule!
  • Define two messages with exactly these names:

  • Tell the model binder to use that particular resource file:

public static void InitializeLocalization()
    ClientDataTypeModelValidatorProvider.ResourceClassKey = "GlobalResources";

You might have seen DefaultModelBinder.ResourceClassKey for a similar purpose. Apparently this property is not used any more…

And now it works:

Wonder why it works in that twisted way?

“Aside from the standard localization of MVC, this message isn’t easily changeable (it was added at the last minute, and we didn’t offer an override unfortunately).” see here, one of Brad Wils‘ comments.



Just for completeness: All this is based on the fact that MVC uses jQuery unobtrusive validation. Should you be using jQuery validation directly, you have to adjust $.validator.messages. See here for a complete example.

That’s all for now folks,

January 13, 2014

ASP.NET MVC I18n – Part 6: Using .NET Resources

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 6:47 pm

The last part addressed larger chunks of HTML content. In that case, imperative coding works nicely. For labels, menu links and similar texts however, the standard localization mechanism in .NET is resources, based on manifest resources, and respective satellite assemblies.

Note: This post is part of a series

Access is handled via the ResourceManager class, additionally Visual Studio will generate an accessor class for each .resx file, that offers members for each key. This eliminates the possibility of typos and provides more convenience through intellisense. For MVC applications it is necessary to change the access modifier for that class to public, as shown here:

The reason is that ASP.NET works with code generation for views (WebForms as well as Razor), thus the generated code lives in another temporary assembly, not the one associated with the web project, and won’t have access to an internal class.

Please note that this applies to the generated accessor class, not the resource itself. One can always use ResourceManager and access a resource in any other assembly.

And to get another point out of the way: With ASP.NET WebForms you might have used the special folders App_GlobalResources and App_LocalResources to place your .resx files in. Don‘t do that with ASP.NET MVC!

The problem is that resources files in these folders are treated differently by Visual Studio and the ASP.NET runtime. There are workarounds to make it work, but why rely on quirks if another approach works without.

If you are interested in the background, Scott has further information.


I chose to place my resources in my own special folder. Since the obvious name for that folder (“Resources”) is already taken (by the default resource file generated from the project settings as well as as namespace by App_GlobalRessources), I named it Localizations:

The resource file Labels.resx and its localized version Label.de-DE.resx contains all navigation labels used in menus and other links.

Adding this folder to the web.configs (the one in the Views folder)…

…makes the view code even more convenient:

<ol class="round">
    <li class="one">
        @Html.ActionLink(Labels.Navigation_Stock_Index + "…", "Index", "Stock")

Proper localized information in respective .resx files available, and we have the next localization step solved:


Final hint: I can live with that approach, i.e.maintain resources in arbitrary files, that I organize as I like. Should you want to “attach” resources to you views and have them used automatically, you might want to have a look at Matt’s post. It should also be possible to implement a simple fallback scheme that allows keeping general labels automatically in one centralized resource file, while maintaining specific labels in view specific resource files.

That’s all for now folks,

December 14, 2013

ASP.NET MVC I18n – Part 5: Imperative View Localization

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 10:58 am

This is going to be a simple one…

Note: This post is part of a series

The most simple way to accommodate different languages is by direct, imperative coding. E.g. images can be localized by maintaining the region as part of the filename and appending it via code. So, let’s make our language switcher from earlier a little nicer:

<a href="@url"><img src="~/Content/flag_@(currentCulture.Name).gif" height="12" width="20" />
     <img src="~/Content/arrow.png" height="12" width="9" />
     <img src="~/Content/flag_@(nextCulture.Name).gif" height="12" width="20" /></a>

Resulting in respective flag images in the upper right corner:


As another example, that feedback message regarding the UI‘s region could be localized the following way:

@switch (UICulture)
    case "de-DE":
        <p>Derzeitige Sprache ist: @UICulture</p>
        <p>Current culture is: @UICulture</p>


For smallish content that certainly works, but once the affected fragment spans considerable amount or even most of the view, it‘s probably better to provide separate partial views. For example for the feature text (the blue area) on the index view:

@{ Html.RenderPartial("_Index_featured_" + UICulture); }

… which uses the _Index_featured_en-US.cshtml and _Index_featured_de-DE.cshtml partial views respectively. Careful, though. There is no fallback in this code, meaning you have to provide all localized versions, which may not always be necessary or feasible. However, it‘s quite easy to come up with a helper method, that looks for the respective files and implements proper fallback strategies.


This imperative approach works well for the occasional demand. However, if this becomes a regular demand, you will start looking for better solutions. E.g. you might want to place the localized views beside the regular ones with the region as part of the filename (or in region specific folders with the same filename). Just be careful that you preferred strategy does not collide with other features, such as mobile views or areas. (There are already too many competing demands.)

I do not need to walk you through respective solutions however, as Vlad has already written about the topic. He adds region specific view folders and evaluates them using his own view engine (for WebForms, but the principle holds for Razor as well). You could of course apply a different naming scheme, e.g. attach the region to the view name itself.

That’s all for now folks,

December 8, 2013

ASP.NET MVC I18n – Part 4: CSS Styles

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 11:18 am

We have our user‘s language choice acknowledged and can start making use of it.

Note: This post is part of a series

Let‘s start with a topic that is not exactly MVC (which is probably why so many tutorials don‘t mention it), but I would like to get it out of our way: region specific information in CSS style sheets.

Of course it is a characteristic of ASP.NET MVC, compared with classical WebForms, that one needs a far better understanding of the underlying technologies, such as HTTP, HTML, CSS. So, in a way, talking about CSS is very much in line with ASP.NET MVC ideas…

For my little sample application I provided the logo image as background image of the header:

<div class="content-wrapper head">
<div class="float-right">
<section id="login">
                    @{ Html.RenderPartial("_SetPreferredCulture"); }

The background comes with the head style:

.head {
    background-image: url(‘logo_en-US.png’);
    background-repeat: no-repeat;
    height: 100px;

That much s independent of the region.

For the region to come into play, we need it present in our html content, which is usually done on the root element in _layout.cshtml:

<!DOCTYPE html>
     <html lang="@UICulture" xml:lang="@UICulture">

UICulture is readily available from the view class. Putting the language in the lang and the xml:lang attribute (provided you maintain XML conformity) – and omitting it anywhere else, like in the http-equiv header Content-Language – is the recommended way of providing this information.

Also here: “The Content-Language value for an http-equiv attribute on a meta element should no longer be used. You should use a language attribute on the html tag to declare the default language of the actual text in the page.”


Now we can use the lang pseudo-class in CSS to provide two different backgrounds:

.head {
    background-image: url(‘logo_en-US.png’);
    background-repeat: no-repeat;
    height: 100px;
:lang(de-DE) .head {
    background-image: url(‘logo_de-DE.png’);

And it works, too Zwinkerndes Smiley

That‘s it. Simple and easy.


One (rare) pitfall…

Suppose the current culture is „de-DE“ (and and advertised on the lang attribute on the HTML element), and the application has some „information area“ for arbitrary content. If that particular content is only available in English, you might want to set the lang attribute of the respective DIV to „en-US“, perhaps to show some flag as background.

Now, common expectation and standards would agree that the DIV and it’s content would now be English instead of German:

“An element inherits language code information according to the following order of precedence (highest to lowest):

  • The lang attribute set for the element itself.
  • The closest parent element that has the lang attribute set (i.e., the lang attribute is inherited).



And in HTML5:

“To determine the language of a node, user agents must look at the nearest ancestor element (including the element itself if the node is an element) that has a lang attribute in the XML namespace set or is an HTML element and has a lang in no namespace attribute set. That attribute specifies the language of the node (regardless of its value).”


In other words; The language is determined by looking for the lang attribute in the parent elements until found. This would imply that the language of a node and its subnodes changes with a lang attribute.

What actually happens, however – in IE and Firefox anyway – is that the language does not change, but is added. Both language tags, the one on the DIV and the one on the HTML element are “active”. And also CSS styles for both languages that use the pseudo-class. So the little image you wanted to indicate the language is determined by the precedence of the language dependent styles – not the language itself.

Granted, it’s rarely an issue. But if it is it can be very annoying!


That’s all for now folks,

November 30, 2013

ASP.NET MVC I18n – Part 3: Custom Language Choice

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 5:49 pm

The last post showed how we could honor the language preferences the user declared in his browser. However, it is also good practice to let the user change the region, independent of the browser settings.

Note: This post is part of a series

To achieve this, we need:

  • a way to maintain the user’s culture choice overriding the browser preferences
  • a way to actually change the preferred culture


Maintaining the preferred culture… 

As we know, each request comes with the accept-language header, telling us language preferences set in the browser. We need something similar to maintain the overriding culture choice.

One option, that is used very often used, is including the region in the URL. This implies addressing the culture in every route declaration, and every action link needs to provide the culture as additional parameter.  Alex shows how the URLs can be analyzed and the culture applied using a custom MvcRouteHandler; Nadeem does it in a Controller base class with similar intentions. Something in the same line should be possible for generating URLs (e.g. with a custom route class).

This certainly works and there is nothing wrong with it. Still, I don’t like this approach all that much. From a technical perspective, URLs in static content like CSS files are still not addressed properly. Additionally there are also other MVC features affecting URLs as well, e.g. areas, which might cause problems. And from a more “semantic” perspective, URLs are meant to address "resources" – which is a hard enough task already. Language preferences, similarly to skin and other profile data, is kind of "orthogonal" information affecting the rendering, but not addressing the resource. Unfortunately MVC does not really give an answer on how to pass that kind of information, which is why you can find all possible approaches (URL parts, query params, cookies, user session, …), none of which is always good or always bad.

For the problem at hand, the preferred culture, my choice is using a cookie: Adjusting the URL feels too invasive, query params are too error prone, and no need to enforce a session.


Setting the culture in a cookie is quite simple:

const string CookieName = "PreferredCulture";

public static void SetPreferredCulture(this HttpResponseBase response, string cultureName)
    SetPreferredCulture(response.Cookies, cultureName);

static void SetPreferredCulture(HttpCookieCollection cookies, string cultureName)
    var cookie = new HttpCookie(CookieName, cultureName);
    cookie.Expires = DateTime.Now.AddDays(30);
    Debug.WriteLine("SetPreferredCulture: " + cultureName);

Reading likewise:

static CultureInfo GetPreferredCulture(HttpCookieCollection cookies)
    var cookie = cookies[CookieName];
    if (cookie == null)
        return null;
    var culture = GetCultureInfo((string)cookie.Value);
    if (culture == null)
        return null;
    if (!SupportedCultures.Where(ci => ci.Name == culture.Name).Any())
        return null;
    return culture;

I don’t trust the cookie to contain a valid value. Call me paranoid, but somebody could have tampered with the request.

And we need to change our method to determine the current culture based on the cookie value:

public static void ApplyUserCulture(this HttpRequest request)
    ApplyUserCulture(request.Headers, request.Cookies);

static void ApplyUserCulture(NameValueCollection headers, HttpCookieCollection cookies)
    var culture = GetPreferredCulture(cookies)
        ?? GetUserCulture(headers)
        ?? SupportedCultures[0];
    var t = Thread.CurrentThread;
    t.CurrentCulture = culture;
    t.CurrentUICulture = culture;
    Debug.WriteLine("Culture: " + culture.Name);


Changing the preferred culture…

Now that we have the groundwork in place, we need to surface the feature to the user. Starting MVC-like with a controller and action to set the preferred culture:

public class CultureController : Controller
    // GET: /SetPreferredCulture/de-DE
    public ActionResult SetPreferredCulture(string culture, string returnUrl)
        if (string.IsNullOrEmpty(returnUrl))
            return RedirectToAction("Index", "Home");
        return Redirect(returnUrl);

And the necessary route…

var route = routes.MapRoute(
    name: "SetPreferredCulture",
    url: "SetPreferredCulture/{culture}",
    defaults: new { controller = "Culture", action = "SetPreferredCulture", culture = UrlParameter.Optional }

For the UI it’s really up to you how you present the choice: some drop down list is quite common. I intend to provide a single action link that simply choses the next supported culture, thus repeatedly clicking it would cycle through all cultures. For this a little helper method makes life simpler:

public static void GetSwitchCultures(out CultureInfo currentCulture, out CultureInfo nextCulture)
    currentCulture = Thread.CurrentThread.CurrentUICulture;
    var currentIndex = Array.IndexOf(SupportedCultures.Select(ci => ci.Name).ToArray(), currentCulture.Name);
    int nextIndex = (currentIndex + 1) % SupportedCultures.Length;
    nextCulture = SupportedCultures[nextIndex];

Based on the work so far I can implement a _SetPreferredCulture.cshtml partial view:

    // cycle through supported cultures
    System.Globalization.CultureInfo currentCulture;
    System.Globalization.CultureInfo nextCulture; 
    MyStocks.Mvc.Helper.CultureHelper.GetSwitchCultures(out currentCulture, out nextCulture);
    string currentCultureDisplayName = currentCulture.Parent.NativeName;
    string nextCultureDisplayName = nextCulture.Parent.NativeName;
    string linkText = currentCultureDisplayName + " => "+ nextCultureDisplayName; 
    string url= Url.Action("SetPreferredCulture", "Culture", new { culture = nextCulture.Name, returnUrl = Request.RawUrl });
    @Html.ActionLink(linkText, "SetPreferredCulture", "Culture", new { culture = nextCulture.Name, returnUrl = Request.RawUrl }, null)

Include it in the _Layout.cshtml view and my users can change their culture as they wish:



That’s all for now folks,

« Newer PostsOlder Posts »

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.


Get every new post delivered to your Inbox.

Join 244 other followers