RSS

Internationalization Aspects for Web Applications

Making web applications that supports multiple languages might be a challenging to maintain. So before building you should consider several aspects that are concerned with internationalization.

In summary very often it is not only translating the texts to other “languages” but also supporting “specific culture/locale”s as well!!!.

First of all there are certain terms that are often described when it comes to supporting multiple languages.

Internationalization (I18n)

In software applications, internationalization (often shortened to “I18N , meaning “I – eighteen letters and then a -N”) is the process of planning and implementing applications and services so that they can easily be adapted to specific local languages translations and cultures, a process called localization(which described below) which also means making your applications and services “localizable”.

In Other words the process of changing your software so that it isn’t hardwired to one language/locale/culture.

 

Localization (l10n)

The process of adding the appropriate resources to your software so that a particular language/locale is supported. This often includes adding language translation files without re-implementing/rebuilding your application.

 

Approaches to Localizing Web Applications

For web applications you can either do the translations in server side or do it in the client side. This almost always depends on the way your web application has been developed. ie. if it is a SPA application written with AngularJS then doing the translations in client side is preferable.

 

Server Side Translations for ASP.NET Applications

Obvious choice is to use the .NET framework support to create resource files(.resx) in the application and get the framework support to set CurrentCulture and CurrentUICulture for the current request thread. You need to suffix resource files with standard culture acronym and appropriate resource values will be selected by framework. Visual studio has builtin support for managing resource files.

resources

In summary “CurrentCulture” will be used for date formatting, number formatting etc. and the CurrentUICulture will be used for resource translations. You can configure the settings as following in Web.config file.

<configuration>
<system.web>
<globalization culture="auto:en-US" uiCulture="auto:fr" />
</system.web>
</configuration>

 

Use of “auto” in globalization setting.

We can set the current culture and “ui culture” as shown above with “auto” prefixed setting. when we use “auto” client user browser’s settings will be used to detect cultures and if not present will be defaulted to “en-US” and “de” in above example. This is through accept-language” request header as shown below. These settings are typically found in OS level or changeable in browser settings.

accept-language

 

Set Current Culture and Current UI Culture Programatically

For ASP.NET applications culture settings can be set at application_beginrequest or application_aquirerequeststate. This will affect all web pages unless they have been written at page level as describe below

void Application_BeginRequest(object sender, EventArgs e)
{
  Thread.CurrentThread.CurrentCulture = new System.Globalization.CreateSpecificCulture("en-US");

  Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
}

Overriding Culture at Individual Page Level(ASP.NET Web Forms)

ASP.NET web forms has a virtual method called  “InitializeCulture” which can be overridden to change culture settings at page level as shown below.

protected override void InitializeCulture()
{
        Thread.CurrentThread.CurrentCulture = 
            CultureInfo.CreateSpecificCulture("en-US");
        Thread.CurrentThread.CurrentUICulture = new 
            CultureInfo("en-US");

        base.InitializeCulture();
}

Client Side Translations

For web applications client side translations are often done with the help of JSon files which acts as resource files.

Localization for Angular JS

Angular Js has built in support for datetime, currency simbol and number format culture support via https://docs.angularjs.org/guide/i18n. Language translations to be done easier in AngularJS, we can use https://github.com/angular-translate/angular-translate library.

In brie your angular application’s config phase you need to configure the translate provider service that provided with the library with some basic settings ie. path to language translation resources folder etc.  as shown below

function configure($logProvider, routerHelperProvider, exceptionHandlerProvider, $translateProvider) {
$translateProvider
 .addInterpolation('$translateMessageFormatInterpolation')
 .preferredLanguage('en')
 .fallbackLanguage('en')
 .useStaticFilesLoader({
 prefix: '/app/i18n/',
 suffix: '.json'
 });
}

You can maintain the translation files JSON in your project as indicated below

translation folder

translation json content

Translation JSON Example (Spanish-es)

Within the UI language translation key can be used with the directive given by the translation library as indicated below.

translation in UI

Above the “translate” is a directive given by angular translate library. “Splash_Msg” is a key in translation file which will be included in run time.

Internationalization Concerns

  • Date Time – Week month name translations should be done to support localization. It is often easier to find and use controls that supports these concerns or build your own that supports these features. When date time period calculations done it is often easier to do it with base neutral culture.
  • calendar

    French and English Language Supported Date Picker

    Bootstrap UI DateTime Picker (http://plnkr.co/edit/nLw9DMgOLDK1dTIOJq4Q?p=preview)

    Date time related concerns are probably be the most complex and challenging concern in localization. Time Zone related conversions are extremely hard to deal accurately in web applications with different locales.

  • Unit of Measure – This might be probably not very important but some parts of the world it is often specific units are being used when displaying data. e.g., in Russia, it is normal to use Russian abbreviations (in Cyrillic letters) instead of standard symbols, e.g. кг and not kg.
  • Monetary conversions – It is often useful to display monetary values with locale specific currency units or using money symbols specific to the culture. Frameworks like .NET framework and Angular l18n supports currency formatting and currency symbols but biggest concern is exchange rates.
  • Numeric Formats – In some cultures symbols have been used for different purposes. e.g. Comma and period being used  alternatively for decimals  33.3 (English) > 33,3 (German). Client side validations and server side validations should be used with care for these concerns and additional coding has to be done.
  • String translations – String translations for static string labels are relatively easier to do when it compared to culture specific formatting. Resource files with different languages are often used.

Language/Culture Selections

Culture and language selections can be done in variety of ways in web applications. It can be detected automatically based on request information or can be set by user as briefly described below.

  • Browser settings
    • accept-language http header present in request headers
    • Location of the client – Based on client request remote IP location can be detected and hence the culture can be set automatically.
  • User Selections
    • User selects language – Within the UI we can let user to select preferred language and change the language in user interface.
    • Store it in profile – Based on user registration or in user profile page we can set the language and culture.

What to Translate

  • Static Texts – Static text labels are relatively easily factored out to resource files
  • Application Data – Application data is probably one of the most difficult to be translated unless you use a dynamic translation service to translate data(e.g. Google Translate). It is difficult and inefficient to “store” these translation data and will be difficult to maintain highly changing data to be maintained with different languages unlike static text labels etc. present in a web site.
  • Error Messages – Error messages should also be translated to specific languages. Specially the client side validation script should be written to support multiple langues.
Advertisements
 
Leave a comment

Posted by on April 22, 2016 in .NET, AngularJs, ASP.NET, Javascript

 

Tags: , , , , ,

Using JSX With Bable to Write React JS Components

I have been working on number of AngularJS and lately into React JS development as well. If you write ReactJs components just using pure JavaScript it might be tedious task to write virtual DOM to actual browser DOM friendly structure that is necessary by the framework in JavaScript.

Eg.

var Menu = React.createClass({
    render: function () {
       return React.createElement("nav", {
         className: "nav navbar-default"
    },
        React.createElement("div", {
          className: "container-fluid"
        },
          React.createElement("ul", {
            className: "nav navbar-nav"
          },
            React.createElement("li", {
              className: "active"
            },
              React.createElement("a", {
                className: "active",
                  href: "#"
              }, "Home")),

           React.createElement("li", {
              className: ""
           },
              React.createElement("a", {
                className: "",
                href: ""
               }, "Contact Us")))));
              }
});

ReactDOM.render(React.createElement(Menu, null), document.getElementById("menu"));

As shown below all above code is just about rendering following simple html menu :-).

menu

Actually this is an insanely unmaintainable structure and this kind of structure is indeed for ReactJs to build the virtual DOM structure that is being internally used.  One obvious choice that given by ReactJs authors is to utilize a transpiled language.

What is Transpilation?

Transpilation is converting one programing language grammar into another programing language typically trough compilation.

One such compiled language is React JSX or React JS extensions.  So React JSX is a language which transforms from a XML like syntactic sugar into actual JavaScript. XML elements, attributes and children are transpiled into arguments that are passed to React.createElement with appropriate nested structure.

How to Use JSX?

One popular  JSX transpiler is Babel.

To setup Babel go to root of your application and execute following in your node command prompt,

npm install babel-cli --save-dev

Note: You need to install NodeJs and npm for this to work

Next we need to setup React for Babel with following.

npm install babel-preset-react -- save-dev

Above will install react transpiler plugin support in node for Babel.
Next we need to setup basic package.json script to easily transpile our JSX files. To that we need to tell in which folder we have JSX files and into which folder the transpiled files should be copied as shown below in package.json file.

  "name": "reacttest",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "devDependencies": {
    "babel-cli": "^6.6.5",
    "babel-preset-react": "^6.5.0"
  },
  "scripts": {
    "build": "babel js -d built --presets react"
  },
  "author": "",
  "license": "ISC"
}

In above we include “babel js -d built –presets react” which tells that “js” folder is where we have JSX files and “built” folder is where we need to copy transpiled files. As indicated in my project explorer below.

project explorer
Babel Transpilation Source And Target Folders

So we can rewrite the initial menu example with JSX as shown below in the react component,

var Menu = React.createClass({
    render: function() {
       return (
<nav className="nav navbar-default">
<div className="container-fluid">
<ul className="nav navbar-nav">
	<li className="active"><a className="active" href="#">Home</a></li>
	<li className=""><a className="" href="">Contact Us</a></li>
</ul>
</div>
</nav>

       );
    }
});

ReactDOM.render(React.createElement(Menu, null), document.getElementById("menu"));

Notice the return statement where you just return more close to HTML version of XML(please note the use of “className” instead of standard “class”). This will be transpiled into native JavaScript that will be syntactically identical to our code sample with code to build the react component if we execute below command in Node command prompt.

npm run build

this will run “build” npm script to compile with babel as shown below.

babel transpilation
Bebel Transpilation Step

Furthermore, you can integrate this command to Gulp or Grunt task runners which maybe to include a development build workflow to make this bit easier.

 
Leave a comment

Posted by on March 12, 2016 in ASP.NET, Babel, JSX, React

 

Tags: , , , ,

Limiting Number of Concurrent Threads With SemaphoresSlim

Coordinating concurrent actions for a predictable outcome or in one word synchronization with concurrent programming is a sometimes a challenging task. There are three main ways of achieving this.

  1. Exclusive locking
  2. Non-exclusive locking
  3. Signaling

Problem
I was working on an external image downloader service which heavily used C# async processing for downloading thousands of images through internet. Downloader tool was too fast due to async nature so there were occasional failures at runtime due to excessive use of network and exceeding resource capacity in the server.

Using Non-exclusive locking for limiting concurrency
Nonexclusive locking is useful in limiting concurrency where preventing too many threads from executing particular function or section in your code at once.  I used SemaphoreSlim which lives in System.Threading namespace. There are two  similar versions of this construct which are Semaphore and  SemaphoreSlim. However latter has been introduced in .NET 4 and has been optimized for performance. So we should better use it.

So how does SemaphoreSlim limits concurrency?
The way semaphore slim work is extremely simple to understand as shown in diagram below.semaphoreslim

The way it work is analogous to a hall that has “N” number of seats for people and has two does to enter and exit. When hall filled with people people has to wait near entrance door until someone goes out from exit door. Maximum number of threads that can be active in semaphore will be limited. It is configurable in SemaphoreSlim constructor. I have also moved this to a configurable value.

private SemaphoreSlim _mysemaphoreSlim = new SemaphoreSlim(Configuration. MaxConcurrency);

Following is very simple method shell that you might need to limit concurrency.

private async Task&lt;bool&gt; AsyncMethod()
{
    this._ mysemaphoreSlim.Wait();

    /* Do the other cool things here, Only N number
    of threads can be between Wait and Release */

    /* After finishing your work, call release this will
    allow to enter another thread if any waiting to execute */

    this._mysemaphoreSlim.Release();
}

 

You could also use

 mysemaphoreSlim.WaitAsync()

if you need waiting threads to be utilized as non-blocking synchronization.

 
Leave a comment

Posted by on February 2, 2016 in .NET, C#

 

Tags: ,

Automatically Restart Node For Application Changes With Grunt

When you are building applications with node at start it might be very annoying to restart node js server when you do a change to a js file. Each time you do a server side non public Js file change you need to restart server to reflect those changes to be seen in client side(browser). This is not necessary to static resources.

One quick way to avoid this workflow is to use grunt to restart your server when there is a file change in your js files. If you are new to grunt, Grunt is node package more of like a build tool that can be used to run various build time tasks in your applications.

First step is installing latest version of grunt in your project. Here make sure you save this as a dev dependency but not as an actual dependency.

npm install grunt  --save-dev

Secondly you have to make sure grunt command line client is installed.

npm install grunt-cli –g

To monitor server side js changes you need to install grunt node monitoring package.

npm install grunt-nodemon  - -save-dev

In your NodeJs project root you need to create gruntfile.js which is basically acts as configuration file for grunt.

node project

You can enter grunt file content as following.

module.exports = function(grunt) {

  grunt.initConfig({
    nodemon: {
      all: {
        script: 'app.js',
        options: {
          watchedExtensions: ['js']
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-nodemon');
  grunt.registerTask('default', 'nodemon');
};

Your application entry point Js file should be included for node mon’s “script” config property value in my case which was “app.js”. Once you have done this all you have to do is just type “grunt” in you terminal.

node autorestart

You can enter “rs” to restart node at any time if you change a server side non public js file you would see nodemon is restarting the node server avoiding you to do it manually and avoiding the annoyance as you would see in terminal window.
node autorestart 2

 
1 Comment

Posted by on December 25, 2015 in ASP.NET, NodeJs

 

Tags: ,

Fixing Canvas Image Rendering Issues With Cross Origin Resource Sharing (CORS)

I was working on integrating photosphere library which will render 3d images to 3d image gallery. This library internally heavily uses Three.js 3d capable JavaScript library. Initially everything was working fine but when we access CORS enabled image domain canvas images were not rendered and no errors logged in console. Issue was library internally fetch ajax request to image source and there is no option to set “withCredentials”. I simply extended library to have this option enabled. But more importantly another issue was by default library was setting “crossorigin” attribute to “anonymous” in canvas image renderer.
Following is the code from

https://github.com/JeremyHeleine/Photo-Sphere-Viewer/blob/master/photo-sphere-viewer.js#L362.

// CORS when the panorama is not given as a base64 string
if (!this.config.panorama.match(/^data:image\/[a-z]+;base64/)) {
loader.setCrossOrigin('anonymous');
}

Again I extended library little bit to include this as an option in initialization configuration object. When setting this to appropriate setting fixed my issue. I will share forked library with my fixes. Actually this issue is worth noting as it might be more commonly encountered in image canvas processing libraries. Actually there is nothing wrong with these libraries but CORS used for images causing issues(depending on your requirement). Finding the cause of these issues might be tedious hence thought of sharing this in this blog post.

HTML specification now has a crossorigin attribute for resources that allows images defined by the element loaded from foreign origins to be used in canvas as if they were being loaded from the current origin(W3C Source : http://dev.w3.org/html5/spec-preview/urls.html#cors-enabled-fetch).

You can use CORS enabled images without cross origin heads but it will seal the canvas so that it will be unchangeable afterwards (which is known as “tainted canvas” for security reasons such as users from having private data exposed by using images to pull information from remote web sites without permission.)
So in summary CORS enabled images can be reused since it will prevent tainting as described above.

var img = new Image(),
canvas = document.createElement(&quot;canvas&quot;),
ctx = canvas.getContext(&quot;2d&quot;),
src = &quot;http://mydomain.com/image&quot;; // image url goes here

img.crossOrigin = &quot;use-credentials&quot;; // or anonymous (which is what this post is
// focused on)

img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage( img, 0, 0 );
}
img.src = src;

 
Leave a comment

Posted by on November 30, 2015 in ASP.NET

 

Configuring Redis Session State Provider With Azure

Redis is an open source (BSD licensed), in-memory data structure store, used as database, cache and message broker. Even though it has been originally developed for POSIX systems it can be easily configured to store session data in .NET with the aid of couple of nugget packages and using windows port that can be downloaded from https://github.com/MSOpenTech/redis.

One particular need you might need to store session external to webserver itself is when you have a web farm/multiple webservers with an authenticated user where subsequent requests would be redirected to different servers for example via a load balancer. Traditionally this can be solved easily with session store providers but using Redis for this can be fast and easier if you have your host system in Azure which was in my case.

To test the implementation locally for development you could do following,

  1. Download Redis port for windows from https://github.com/MSOpenTech/redis. Note: it is not available in http://redis.io site.redis windows port extract
  2. 2. Starting local Redis server is very easier as indicated below.

redis server

It will start the Redis server and note the connection details. You can change these by changing redis.conf file which is documented in the site.

e.g. https://github.com/MSOpenTech/redis/blob/2.8/redis.conf

redis server start

3. You can use various commands specified in the project site’s documentation e.g. to view session keys use command below. (not to worry on hacking my servers these are my DEV ENV values )

redis keys

4. Then you have to do install redis session state provider nugget package from https://www.nuget.org/packages/Microsoft.Web.RedisSessionStateProvider/ to your project.

5. One caveat here is to support “sliding expiration” for session state you need to make sure you install package version >=1.5.0. Sliding expiration is typically a must in session state management. Current version at the time of writing is 1.6.5 so make sure you install the latest.

6. To install RedisSessionStateProvider, run the following command in theNuget Package Manager Console of Visual Studio.

PM> Install-Package Microsoft.Web.RedisSessionStateProvider -Version {latest version number here}

7. Then all you have to do is add following configuration section in your web.config and change values accordingly.

session state config

8. After you have successfully tested it in your development environment you might need to configure Redis in windows Azure. Creating Redis Cache in Azure is super easy as shown below. At the time of writing it will be only supported in new Azure portal found in http://portal.azure.com/. Old portals does not support Azure Redis Cache.

azure redis create

azure redis create 2

9. Choose appropriate pricing tear depending your data load.

azure redis pricing

10. It will take a while to create the Redis cache. It sometimes takes more than 10 minutes to up and gets running.

redis cache creating

11. After you create Redis cache you need to configure cryptographic key and connection details for the nuget package. Selecting created Redis cache will show the access keys as below.

redis session config cryptographic keys

12. Then all you need to do is enter Access key and host name of azure redis server to the web.config. Notice how the connection details being entered, its quite different than we used earlier for local Redis server. Also note that host name given by Microsoft is always ends suffixed with cache.windows.net. So your full host name should look like someuniquename.redis.cache.windows.net. This will essentially point your session store to Azure Redis cache.

redis session config values

Note: Redis desktop manager can be used to manage Redis DB if you prefer GUI interface which can be download at http://redisdesktop.com/

redis desktop manager

 
Leave a comment

Posted by on October 20, 2015 in .NET, ASP.NET, ASP.NET MVC, Azure, C#

 

Tags: , , , , ,

PowerShell Script to Add Current IP Address to Azure FireWall Rules

When you are connecting to Azure databases it is necessary to add current public IP address to the Azure firewall rules to white list your public IP. This can be done via azure management portal but this might be annoying at sometimes especially when you’re IP changes with router restarts where you are not under a static public IP. The other drawback is automatic firewall rule generated via portal is the firewall rule names will clutter up in firewall rules table and you should remember to clean these unnecessary IP addresses to avoid not only to remove unnecessary IPs but to avoid security risks with public ISP provided dynamic IPs from the pool.

You could automate this by relatively easily by using PowerShell script as described below. In order for it to run you should import azure publish settings profile. Script uses certificate based authentication that can easily be achieved by importing publish settings profile. Note: this should be done in your azure management computer so after importing publish settings to your management machine’s certificate store, you can issue powershell azure cmdlets without explicitly needing to enter Azure credentials.

1. Run Windows PowerShell as an administrator as follows:
Choose Start, in the Search box, type Windows Powershell then Right-click the Windows PowerShell link, and then choose Run as administrator.

2. At the Windows PowerShell command prompt, type Get-AzurePublishSettingsFile and then press Enter.
3. Web browser opens with azure management portal and log in to it and follow instructions to download publish profile.
4. Once you have downloaded publish profile, import the publish profile by entering following command in Powershell command prompt.
Import-AzurePublishSettingsFile ‘{pathtopublishsettingsfile}’

5. If no error fired up then entering Get-AzureSubscription in powershell should show current subscription(s).

get-current-subscriptions

6. Once you have done that you can run the following PowerShell script by changing variables to appropriate values as shown below. You can save this to “ps1” type file(powershell script file) and execute the script through power shell when necessary or even better “PS2EXE” method as described below.

  • $subscriptionName – Get the subscription name from “Subscription Name” field got from above step 5
  • $firewallRule – Fire wall rule name which is something descriptive to you eg. Dimuthu-Home
  • $serverName – Your server name

Note : Full script can be downloaded at here...


$subscriptionName = 'Your Subscription Name'
$ipGetCommand = 'http://www.iplocation.net/find-ip-address'
$firewallRule = 'Dimuthu-Home'
$serverName = "Your Azure Server Instance Name";
$webclient = New-Object System.Net.WebClient
$queryResult = $webclient.DownloadString($ipGetCommand)
$queryResult -match '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b'
$currentPublicIp = $($matches[0])

Select-AzureSubscription -SubscriptionName $subscriptionName

If ((Get-AzureSqlDatabaseServerFirewallRule -ServerName $serverName -RuleName $firewallRule) -eq $null) {
    New-AzureSqlDatabaseServerFirewallRule -ServerName $serverName -RuleName $firewallRule -StartIpAddress $currentPublicIp -EndIpAddress $currentPublicIp
}
else {
    Set-AzureSqlDatabaseServerFirewallRule -ServerName $serverName -RuleName $firewallRule -StartIpAddress $currentPublicIp -EndIpAddress $currentPublicIp
}

7. I have saved this script to “azure-ipenable.ps1” for demo purpose and executed it through PowerShell as shown below. This will create firewall rule with given name i.e. “Dimuthu-Home” if it does not exist or will update the IP address if the firewall rule does exist. This is especially useful when router resets or your dynamic public IP address changes.

after-create-rule-output

Running PS1 Script More Easily By Converting to EXE


To make life more easier when after you change subscription details to appropriate values you could convert it to exe.

First download the PS2EXE utility and follow instructions!
https://gallery.technet.microsoft.com/PS2EXE-Convert-PowerShell-9e4e07f1
Following is the command I used to convert PS script to exe…
ps2exe

This will generate .NET executable that will do the job more easily…:-)

ps2exe output

 
Leave a comment

Posted by on September 16, 2015 in Automation, Azure, Powershell

 

Tags: , ,