Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Internationalize Your ASP.NET Applications (Part 1 of 3)  : Page 3

Not only does ASP.NET simplify Web application development, it also provides comprehensive support for internationalization.

Map Content to Classes
The sample site for this article series is a Web-based content viewer built using ASP.NET that provides news articles in several languages in parallel. The content is stored in several different languages and is displayed to the Web site visitor in the correct language depending on their preference. The site ensures that all article text, page text, dates and images are displayed for the specified culture.

The news site stores its articles in a database, which is common in sites of this type, because it simplifies building management interfaces for editors and journalists. The first step in putting the application together is to build a user interface to display the news stories. The problem lies in controlling which language version is displayed. Here are the simple requirements for the site:

  • The site stores each article in four different languages
  • Users select the language from: English - UK, French - France, Chinese - China and Japanese - Japan.
  • The default language is UK English.
  • The site displays a series of news articles in the selected language (if available).
  • Each article consists of a unique identifier, title, body, and publication date
  • As this is an example, there will be no interface to submit, edit, delete or otherwise manipulate articles. The Test data were inserted directly into the database (SQL Server).
A class called Article represents an instance of an article in a specific language. At the start of the Article.cs class file are some directives for the namespaces you'll need:

using System.Data; using System.Globalization;

The System.Data namespace provides the DataSet class, and the System.Globalization namespace provides classes you use to manage the localization of information. The most important of these is the CultureInfo class, which represents a culture and which you use to specify the culture to be used to display a specific page.

The Article class has private members used to store the identifier, title, body, publication date and culture (each Article instance represents a piece of content in a specific culture).

private int articleID; private string articleTitle = ""; private string articleBody = ""; private DateTime articlePublicationDate; private CultureInfo articleCulture;

Next are some properties for the private fields that will be displayed on the page for each article:

public string Title { get { return articleTitle; } } public string Body { get { return articleBody; } } public DateTime PublicationDate { get { return articlePublicationDate; } } public CultureInfo Culture { get { return articleCulture; } } public int ArticleID { get { return articleID; } }

Nothing to get excited too about there. The SQL Server 2000 database that holds the articles includes a view called ArticleDetail, which returns a dataset that looks like Figure 1:

Figure 1: The SQL Server ArticleDetail view contains data like this.

Each row in the dataset represents a version of an article in a specific language, and each version includes the article identifier, date, title, body and a culture identification string.

Author Note: Although both Access and SQL Server support Unicode, you may need to configure your development machine to display characters in foreign languages by installing additional language support. To do this in Windows look in Control Panel at the Regional settings and you will find an area marked "Language settings for the system". You will need to select each language that you want to use. Clearly, which items you need will vary depending on the current configuration of your machine and the languages with which you intend to work.

The Article class has an overloaded constructor that accepts an integer identifying a specific article and a System.Globalization.CultureInfo object that represents the culture, and returns an Article object.

public Article(int articleID, CultureInfo culture) { }

A SQL query in the constructor uses the two parameters to retrieve the relevant translation of the article.

string Sql = "SELECT * FROM ArticleDetail WHERE ArticleID=" + articleID + " AND LanguageID='" + culture.Name + "'";

The constructor passes the SQL query to a private helper method called GetDataSet() that returns the relevant rows. Here's the Article class code.

using System; using System.Data; using System.Data.SqlClient; using System.Web; namespace Multilingual { public class Database { public static DataSet GetDataSet(string Sql) { DataSet DS = new DataSet(); string myPhysicalPath = HttpContext.Current.Request. PhysicalApplicationPath; string connectionString = "Server=optimism; Database=sqlservername; UID=sqlserveraccountname; PWD=mypassword;"; SqlConnection myConnection = new SqlConnection(connectionString); SqlDataAdapter myDataAdapter = new SqlDataAdapter(Sql, myConnection); DataSet myDataSet = new DataSet(); myDataAdapter.Fill(myDataSet); return myDataSet; } } }

So, the Article class retrieves an article by formulating the SQL statement and passing that to the Database object, which calls the GetDataSet() method:

DataSet dataSet = Database.GetDataSet(Sql);

If the query returns no rows then there is no matching article in the specified culture. In this case, this next block of code runs another SQL query to search for an English version (the default language in the application).

if (dataSet.Tables[0].Rows.Count == 0) { Sql = "SELECT * FROM ArticleDetail WHERE ArticleID=" + articleID + " AND LanguageID='" + "en-gb" + "'"; dataSet = Database.GetDataSet(Sql); }

If, having run the second SQL statement, there are still no rows in the result set then the code throws an exception.

if (dataSet.Tables[0].Rows.Count == 0) { Exception exception = new Exception("Article not available"); throw exception; }

If either query returns a row, the constructor sets the values of the private members for the title, body, publication date and culture.

DataTable dt = dataSet.Tables[0]; articleTitle = dt.Rows[0]["Title"].ToString(); articleBody = dt.Rows[0]["Body"].ToString(); articlePublicationDate = DateTime.Parse (dt.Rows[0]["PublicationDate"].ToString()); articleCulture = CultureInfo. CreateSpecificCulture (dt.Rows[0]["LanguageID"].ToString()); }

The last line of the constructor uses the CreateSpecificCulture() method to create a new CultureInfo object that represents the culture of the article The CreateSpecificCulture method takes a culture string such as 'en-US" and returns a CultureInfo object representing the most appropriate culture.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date