For a website that supports multiple languages, it is important to tell the client what the selected language is. This is done in the <html> tag in the lang or xml:lang attribute and could look something like this for an XHTML document:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">

The DOCTYPE and <html> tag is usually static text that doesn’t get generated by the server, but for localized websites we need to adjust the lang or xml:lang attribute to make it correspond to the selected language.

In ASP.NET this is very easy because the thread knows about the selected language, so all we have to do is to print it out in the attribute in the <html> tag. You can do it easily by inserting directly on the aspx page like so:

<%@ Import Namespace="System.Threading" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=Thread.CurrentThread.CurrentCulture.IetfLanguageTag %>">

As long as you remember to set the selected language, or culture as it’s called in .NET, on the executing thread it will work. You can set it up globally in the web.config or do it manually like so:

CultureInfo lang = CultureInfo.CreateSpecificCulture("en-US");

Thread.CurrentThread.CurrentCulture = lang;

Thread.CurrentThread.CurrentUICulture = lang;

For security reasons Microsoft doesn’t allow invisible columns in a GridView to be posted back like it does in the old DataGrid. That makes it impossible to store the ID of the row in an invisible column and then use it for editing etc. Instead they introduced a much more powerful way of doing the same thing.

Say hello to the new properties DataKeyNames and DataKeys. They allow you to store more than one column of the data source in the ViewState and thus giving you a much easier approach than dealing with invisible columns. In this code sample, I’ll show you how to store a single field in the grid an then use it on a postback.

When you data bind the GridView, you have to tell it in a single line of code what columns of the data source should be saved during postback. In this case, it’s the “id” column.

private void DataBindGrid()
{
  grid.DataKeyNames = new string[] { "id" };
  grid.DataSource = GetDataTable();
  grid.DataBind();
}


After the postback you can then loop through the rows and extract the value “id” column.

private void LoopRows()
{
  for (int i = 0; i < grid.Controls[0].Controls.Count - 1; i++)
  {
    string key = grid.DataKeys[i].Value.ToString();
   
DoSomething(key);
  }
}


You can find more info about how to use the DataKeyNames and DataKeys properties here:

Datagrid to GridView Conversion: No Invisible Columns
gridview column w/visible=false no longer contains cell data in beta 2