---
title: Localizing data on MVC sites
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

To serve content in multiple languages on your MVC site, you first need to set up functionality that detects and sets the current culture for each request. You can then localize the content displayed on the site's pages.

## Enabling localization in MVC projects

If you want to have a multilingual MVC site, you need to set up culture recognition in the MVC project. On the beginning of every request, you need to:

1. Retrieve or determine the correct culture to be used in the current request. The way you detect the culture depends on the implementation of your multilingual site. For example, possible options are culture prefixes in URLs, culture-specific domains, custom cookies, etc.
2. Set the **Thread.CurrentThread.CurrentUICulture** and **Thread.CurrentThread.CurrentCulture** properties of the current thread (available in the _System.Threading_ namespace).

> **Note:** **Note**: _Thread.CurrentThread.CurrentUICulture_ and _Thread.CurrentThread.CurrentCulture_ are properties of the .NET framework and use the _System.Globalization.CultureInfo_ type. They are not directly comparable with the Kentico _CMS.Localization.CultureInfo_ type, or the _CurrentUICulture_ and _CurrentCulture_ properties of the _CMS.Localization.LocalizationContext_ class.

The Kentico localization API then automatically works with the given culture (for example when resolving [resource strings](https://docs.kentico.com/k9/multilingual-websites/setting-up-a-multilingual-user-interface/working-with-resource-strings.md)).

### Example

One common way to determine the culture of page requests is to use culture prefixes in your site's routes. For example:

- English – _www.example.com/**en-us**/path_
- Spanish – _www.example.com/**es-es**/path_

The following code examples showcase how to parse the culture from the route prefix and set the current culture for the MVC application. You can modify and adjust snippets from this example for use in your own projects.

```csharp title="Example - RouteConfig"

using System.Web.Mvc;
using System.Web.Routing;

...

public static void RegisterRoutes(RouteCollection routes)
{
    ...

    // Parses a URL containing a culture route prefix
    var route = routes.MapRoute(
        name: "Default",
        url: "{culture}/{controller}/{action}",
        defaults: new { controller = "Home", action = "Index" },
        constraints: new { culture = new SiteCultureConstraint() }
    );

    // Assigns a custom route handler to the route
    route.RouteHandler = new MultiCultureMvcRouteHandler();
}


```

```csharp title="Example - MultiCultureMvcRouteHandler"

using System.Globalization;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

public class MultiCultureMvcRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        // Retrieves the requested culture from the route
        var cultureName = requestContext.RouteData.Values["culture"].ToString();

        try
        {
            // Creates a CultureInfo object from the culture code
            var culture = new CultureInfo(cultureName);

            // Sets the current culture for the MVC application
            Thread.CurrentThread.CurrentUICulture = culture;
            Thread.CurrentThread.CurrentCulture = culture;
        }
        catch
        {
            // Handles cases where the culture parameter of the route is invalid
            // Returns a 404 status in this case, but you can also log an error, set a default culture, etc.
            requestContext.HttpContext.Response.StatusCode = 404;
        }

        return base.GetHttpHandler(requestContext);
    }
}

```

```csharp title="Example - SiteCultureConstraint"

using System.Web;
using System.Web.Routing;

using CMS.SiteProvider;

// Constraint that restricts culture parameter values
// Only allows the codes of cultures assigned to the current site in Kentico
public class SiteCultureConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext,
                    Route route,
                    string parameterName,
                    RouteValueDictionary values,
                    RouteDirection routeDirection)
    {
        string cultureCodeName = values[parameterName]?.ToString();
        return CultureSiteInfoProvider.IsCultureOnSite(cultureCodeName, SiteContext.CurrentSiteName);
    }
}

```

## Localizing site content

When [retrieving page content](https://docs.kentico.com/k9/developing-websites/developing-sites-using-asp-net-mvc/developing-mvc-applications/retrieving-content-on-mvc-sites.md), load the correct culture version of pages based on the current culture of the request.

For individual text strings displayed on the site (which are not stored within page fields), we recommend using multilingual [resource strings](https://docs.kentico.com/k9/multilingual-websites/setting-up-a-multilingual-user-interface/working-with-resource-strings.md). You can create and edit the strings in the **Localization** application of the Kentico administration interface.

To work with the strings in your code, you can create an alias for the _CMS.Helpers.ResHelper_ class and use the _GetString()_ method:

```csharp

@using Resources = CMS.Helpers.ResHelper;
...
<h2>@Resources.GetString("SiteName.OurProducts")</h2>

```

```csharp

@using Resources = CMS.Helpers.ResHelper;
...
@{
    ViewBag.Title = Resources.GetString("SiteName.OurProducts");
}

```

## Localizing validation results and model properties

The default approach to validating the data model of MVC applications is to decorate the model and its properties with attributes from the [System.ComponentModel.DataAnnotations](https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations\(v=vs.100\).aspx) namespace. You use the attributes to define common validation patterns, such as range checking, string length and required fields.

The _Kentico.Web.Mvc_ [integration package](https://docs.kentico.com/k9/developing-websites/developing-sites-using-asp-net-mvc/starting-with-mvc-development/installing-kentico-integration-packages.md) provides a feature that allows you to use localized [Kentico resource string keys](https://docs.kentico.com/k9/multilingual-websites/setting-up-a-multilingual-user-interface/working-with-resource-strings.md) as error messages in data annotation attributes. The strings are localized based on the current culture context of the current visitor. The _Kentico.Languages.English_ [integration package](https://docs.kentico.com/k9/developing-websites/developing-sites-using-asp-net-mvc/starting-with-mvc-development/installing-kentico-integration-packages.md) (installed with the _Kentico.Web.Mvc_ integration package) contains a _.resx_ filewith the resource strings used in the English localization of Kentico. Aside from that, you can also use the standard resource strings stored in the database.

The feature supports localization of the following data annotation attributes:

- _Display_
- _DisplayName_
- _DataType_
- _MaxLength_
- _MinLength_
- _Range_
- _RegularExpression_
- _Required_
- _StringLength_

### Enabling data annotation localization

1. [Install](https://docs.kentico.com/k9/developing-websites/developing-sites-using-asp-net-mvc/starting-with-mvc-development/installing-kentico-integration-packages.md) the _Kentico.Web.Mvc_ integration package in your MVC application project.
2. In the MVC application's _Global.asax_ file, add the following line in the _Application\_Start_ method:

   ```csharp

   protected void Application_Start()
   {
       ...

       // Enable and configure the selected Kentico ASP.NET MVC integration features
       ApplicationConfig.RegisterFeatures(ApplicationBuilder.Current);
   }

   ```
3. Make sure the feature is enabled in the MVC application's _ApplicationConfig.c&#x73;_&#x66;ile:

   ```csharp

   public static void RegisterFeatures(ApplicationBuilder builder)
   {
       ...
       builder.UseDataAnnotationsLocalization();
       ...
   }

   ```

Once the feature is enabled, the validation results and display names of model properties are localized using Kentico localization services.

```csharp

public class MessageModel
{
...
     [Required(ErrorMessage = "General.RequiresMessage")]
     [Display(Name = "General.Message")]
     [DataType(DataType.MultilineText)]
     [MaxLength(500, ErrorMessage = "General.MaxlengthExceeded")]
     public string MessageText
     {
         get;
         set;
     }
...
}

```

**Note**: The individual error messages are processed by the _System.String.Format_ method and support composite formatting. That is, the strings themselves can contain format items that are specific to each validation attribute and represent their parameters. For example, the _minimum length_ for the _MinLenghtAttribute_ or the _minimum_ and _maximum_ for the _RangeAttribute_.
