Localization – part 2

In my previous article – Localization (a brief introduction) – I gave a very brief overview about how localization can be done, what would be the list of things to be taken into consideration and had given a very small example to how this can be done at the beginners level.
In this article I would like to move on to the intermediary level… Now, that we have identified the localizable entities of the application and how the resource information has to be stored. Let us progress onto
1. Naming Convention
2. How to create resource files
3. Where to store the resource files
4. Retrieving resource information
I have also given a list of steps to create satellite assembly.
I. Naming convention –

The naming convention of .resources file (the binary form of .resx file) is dependent on the namespace of the application.

And the naming convention of a satellite assembly depends upon the assembly name of the application.

basetype.culture.resx – is the naming convention for .resx files.
Example: MyResource.de-DE.resx – this will indicate that this resource file will be used if the culture is set to German(Germany), where “MyResouce” is the basetype and “de-DE” is the culture… (msdn link to CultureInfo class ).
Let us suppose that the namespace of your application is “Chk1.Test1.TestLocalization” and the assembly name has been set as “Test” . The .resources file should be named “Chk1.Test1.TestLocalization.MyResource.de-DE.resources” and the satellite assembly – “Test.resources.dll”
II. Steps to create the resource files–
· Add a default resource file (Let it be – MyResource.resx). For this file the culture needn’t be specified. Add the keys and their respective values. Now, this is the information which will be used by the browser in case the resource files for the set culture is missing.
· Create resource files for the required culture.See to it that the naming convention is followed. Let me assume that I require resources for ja (japanese) and de(German) culture. The name of the resource files should be – MyResource.ja.resx and MyResource.de.resx.
Note 1: One can alternately make use of the option “Generate Local Resource” which has been provided in Tools menu. But, in case of an application with many pages this will not be a very viable option.

Note 2: For the web pages to make use of these resource files based on the UI culture of the browser, the attributes Culture=”auto” and UICulture=”auto” has to be set in the page directive of all the pages being used.

III. Storing resource files –

All the resource files can be stored in the application itself. But, as the number of pages in your application increases, the number of resource files also increases.

Let us assume that you have three resource files and that your application has to be localized into four languages(en-GB, de-DE, fr, ja). The number of resource files now becomes 3×4 = 12 files!

A better and recommended way is to make use of satellite assemblies, i.e the hub and spoke model. Here, the hub constitutes of the main assembly and the default resource; and the spokes are the different satellite assemblies, one for each language.

IV. Retrieving information from the resource files –

You can internationalize your web application by either making use of the default .resx file or Resource Manager.

ForExample, let us consider that your MyResource.resx file contains a keyword – “Button1.Text”

String str = MyResource[“Button1.Text”];

[ or]

ResourceManager rm = new ResourceManager(“MyApp.MyResource”, Assembly.GetExecutingAssembly());

String str = rm.GetString(“Button1.Text”);

or

String str = rm.GetObject(“Button1.Text”); // useful in case the value is not an string.

These above steps retrieve the information based on the culture selected.

Note: Do check this link to know more about how the hub and spoke model for packaging and deploying resourcesuses a fallback process to locate appropriate resources.

V. Steps to create satellite assemblies :

Step 1: Create the required culture’s .resx file –

Let us create resource files for Japanese culture – MyResource.ja.resx

Step 2: Create .resources file (which will have binary format) –

Use ResGen.exe to create the bin file. ResGen can be found in – \Microsoft Visual Studio 8\SDK\v2.0\Bin

Syntax – ResGen.exe basetype.resx AppNamespace.basetype.resources

Example – ResGen.exe MyResource.ja.resx MyApp.MyResource.ja.resources

In this case MyApp is the namespace of the application. In cases where in your app has namespace MyApp.App1.App2 also “MyApp” keyword can be used.

Step 3: Use Al.exe to create the satellite assemblies –

Al.exe can be found in – \Microsoft.NET\Framework\v2.0.50727

Syntax –

Al.exe /t:lib /embed:AppNamespace.basetype.resources /culture:culture /out :AppNamespace.resources.dll

/t:lib - Says you are interested in a .dll.

/embed:AppNamespace.basetype.resources Embeds the resource to a target name to match the Visual Studio IDE naming structure.

/culture:culture - Identifies the culture in which you are interested.

/out: AppNamespace.resources.dll Name of the DLL in which you are interested.

Example –

Al.exe /t:lib /embed:MyApp.MyResource.ja.resources /culture:ja /out:MyApp.resources.dll

This will create the satellite assembly which is specific to Japanese (ja) locale.

Step 4: Place these satellite assemblies in appropriate location

These satellite assemblies should be placed in the bin\culture folder.

In this case folder named ja should be created in bin folder of the application and the newly created satellite assembly AppNamespace.resources.dll should be placed in it.

msdn link for creating satellite assemblies

June 6, 2007 at 1:43 pm 4 comments

Why Precompile???

The advantages of precompiling a web application is that
1. It ensures faster page-load and
2. provides more security to the code.
Here are few articles which will help in understanding precompilation better and also how to precompile an ASP.NET2.0 web application…
http://articles.techrepublic.com.com/5100-3513-6116804.html
http://www.beansoftware.com/ASP.NET-Tutorials/Deploy-ASP.NET.aspx
http://aspalliance.com/717
msdn link
quote – “The primary disadvantages of deployment pre-compilation are that you have to perform these steps prior to deployment and that you can’t change your Website after it has been deployed. If you want to make changes, you have to recompile the Website and redeploy it”
(How to precompile)
Also chk out this article by Rick Starhl titled – “Watch out with precompiled ASP.NET 2.0 Applications if you have Orcas installed http://west-wind.com/WebLog/posts/73663.aspx

May 28, 2007 at 7:39 am 2 comments

Invalid cast from ‘System.String’ to ‘System.TimeSpan….

I have already mentioned in one of my previous blog articles, I am working on a web application which has been converted from 1.1 to 2.0. And because of the many minor changes made in the 2.0 framework, I keep encountering many exceptions!!!

One such exception was raised while making use of Convert.ChangeType method.

When i tried to convert a string to timespan an InvalidCastException was raised. Reason??? In this framework, the method does not support this type of a conversion….

There is the option of using Parse method or TryParse method in TimeSpan class… (TryParse is a newly added method which is very much similar to the Parse method but this doesn’t throw an exception when the conversion fails).

Another thing to keep in mind while using this method is that it doesn’t handle nullables.

May 19, 2007 at 3:46 am 1 comment

Localization (a brief introduction)

Presently, with the increase in the number of non-english users, internationalizing web sites has become quite important. In this article, as the title suggests… I am going to very brief explaination about how a web site can be localized.

To begin with, for localizing a web application a programmer needs to –

1. identify the localizable entities of the application. These can be any one of the following- Text Resource; Graphics; Database content; Dates; and maybe currencies, etc.,

2. is to identify which method of retrieval of culture information. And for this one can make use of the web.config or the page directive or allow the user to select the culture through the application itself

and

3. is to identify how the resource information has to be stored. This can be done by using 1. the Database or 2. the Resource files (.resx files); 3. the Text files (which can be easily converted into a Resource file) or 4. an xml file or 5. an excel sheet.

all this will obviously be based on whatever is suitable for your app.

I created this very simple web application in which i allow the user to either select English(US) or Deutsche (Germany) language and am making use of .resx files to store the resources.

To be more specific, I am going to make use of two pages, SelectLang page and LangIndicator page. The SelectLang page will contain a dropdownlist from which the user can select the required language and the LangIndicator page is going to make use of this selected information to set the current thread culture. And thats it….

langindicator.jpg

May 6, 2007 at 2:42 pm 1 comment

Blogroll @WordPress

What are the different ways in which blogroll can be imported??? (Check out this link and this wikipedia link for better understanding about what a blogroll is. )

This above question has been nagging me for quite a while now and this is what i have come to understand about various ways of importing blogrolls into our blogs –

1. By making use of a javascript

2. via RSS by making use of a given URL.

3. via external PHP code by again making use of a given URL.

4. OPML (Outline Processor Markup Language) link. But the disadvantage of using this method of inclusion, is that recently appended links to the blogroll will not be added to the blog. It has to be later done manually by the user.

Now coming to how one can import their blogroll to wordpress…

WordPress allows its users to import an OPML file. Its quite cumbersome… but this is the only option given to wordpress users.

There are other ways provided to add blogroll links –

1. one way is to make use of the “Add links” option provided in the blogroll editing page

2. and the other way is to make use of “Add to Blogroll” provided in each and every wordpress page. All one has to do is to open the page (it has to be wordpress page) and select this option.

The first method for adding blogroll using “add links” option will allow us to add any link. But this process will not be as simple as making use of either blogrolling or bloglines or google reader

I have heard bad reviews about blogrolling.com, but it allows us to make use of any one of the above mentioned ways of exporting the blogroll contents. And so does bloglines but when it comes to Google reader it allows a person to only export an OPML file.

And because wordpress allows its users to import only an OPML file you might even be interested in using either opmlmanager or opmlworkstation

All these sites allows the user to categorize the links into private or public links. I, for one, am making use of this feature and have added my public blogrolls link to my blog using the “add links” option. And though I am not very happy with this arrangement as it doesn’t exactly serve the purpose of displaying the list in my blog, atleast it allows people to access the list and it doesn’t require me to keep updating the OPML file being used…

 

April 22, 2007 at 6:00 am 5 comments

Defy all challenges

I just now came across this very cool ad for Visual Studio – Defy all challenges

A promotional for – Visual Studio Team System ; Web Development; Windows Vista and 2007 Office System. It has an interactive interface with links to view :

1. Tools and tips – which helps the user in understanding more about the each development tool.

2. Watch the videos – which have links to these very funny videos showing the lighter side of a developers life.

3. Make your own – Allows you to create a new video with the available tools

4. View and vote – This link allows you to select a video created by any new user and rate it.

The ad has been set up in a gaming environment and though I am not the best person to judge about marketing tactics, I would like to say that there is only one word which can be used to describe this promotional – CAPTIVATING!!!

April 12, 2007 at 11:10 am Leave a comment

Exceptions… uggh!!!

I am presently working on a project which make use of remoting… This project was recently converted from .net framework 1.1 to 2.0. All good stories have a bad element. This one had exceptions as the bad guy.

I got three different exceptions one after the other in a loop for the same problem! I have pasted all the exception stack trace information below –

stack trace 1 :

System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine

Server stack trace: at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)\r\n at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)\r\n at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateAuthenticatedStream(Stream netStream, String machinePortAndSid)\r\n at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateSocketHandler(Socket socket, SocketCache socketCache, String machinePortAndSid)\r\n at System.Runtime.Remoting.Channels.SocketCache.CreateSocketHandler(Socket socket, String machineAndPort)

stack trace 2:

System.Runtime.Remoting.RemotingException: Authentication failure —> System.IO.IOException: Unable to read data from the transport connection: The connection was closed.\r\n at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)\r\n at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)\r\n at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateAuthenticatedStream(Stream netStream, String machinePortAndSid)\r\n — End of inner exception stack trace —\r\n\r\nServer stack trace: \r\n at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateAuthenticatedStream(Stream netStream, String machinePortAndSid)\r\n at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateSocketHandler(Socket socket, SocketCache socketCache, String machinePortAndSid)\r\n at System.Runtime.Remoting.Channels.SocketCache.CreateSocketHandler(Socket socket, String machineAndPort)\r\n

stack trace 3:

System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host\r\n\r\nServer stack trace: \r\n at System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult lazyResult)\r\n at System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential credential, String targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel)\r\n at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateAuthenticatedStream(Stream netStream, String machinePortAndSid)\r\n at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateSocketHandler(Socket socket, SocketCache socketCache, String machinePortAndSid)\r\n at System.Runtime.Remoting.Channels.SocketCache.CreateSocketHandler(Socket socket, String machineAndPort)\r\n

After breaking my head for two days I finally found that – This error is raised in .net 2.0 framework. And that by setting “ensureSecurity” property to “false” which will allow the remoting connection to make use of the normal TCP connection rather than Negotiate Stream solves the problem… whew!!!

Then after this exception was cleared. Another exception was raised….

Stack trace:

{“A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond”}

Server stack trace: at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.Connect(EndPoint remoteEP) at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint ipEndPoint) at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket() at System.Runtime.Remoting.Channels.SocketCache.GetSocket(String machinePortAndSid, Boolean openNew) at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWithRetry(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream)

After going through many many sites and many different solutions I finally landed on the correct one, which was – disable the firewall on the host system!!!

But anyways, the other solution which I thought would be helpful to others with a similar exception is – to explicitly disable default proxy support in web.config, which essentially forces a direct connection:

<system.net>
<defaultProxy>
<proxy usesystemdefault=”False”/>
</defaultProxy>
</system.net>

For more information try out this link and this one.

April 11, 2007 at 3:39 am 9 comments


September 2016
M T W T F S S
« Jun    
 1234
567891011
12131415161718
19202122232425
2627282930