user565992
user565992

Reputation: 497

ASP. net core localization with resoucrce data in database

I have an asp.net webforms application which is being upgraded to asp.net core mvc. The current webforms application supports localization and all the resource data is in database tables. I am working on localization for mvc app and want to reuse my database to store the localization resource file information.

Loalization.sqlLocalizer (nuget package ) https://localizationsqllocalizer.readthedocs.io/en/latest/ from my understanding is that it needs to use the database structure defined by the package and is not customizable.

What are my other options or pointers which I can look at to implement this in MVC?

Upvotes: 3

Views: 4465

Answers (1)

Waqas Anwar
Waqas Anwar

Reputation: 360

First of all, you need to store your languages and string resources in database.

  • Languages table can have Id, Name and Culture columns.
  • StringResources table can have Id, Name, Value and LanguageId columns.

Next, generate the EF Core entities related to these database tables.

Here is an example of Language entity

public partial class Language
{
    public Language()
    {
        StringResources = new HashSet<StringResource>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Culture { get; set; }

    public virtual ICollection<StringResource> StringResources { get; set; }
}

Here is an example of StringResource entity

public partial class StringResource
{
    public int Id { get; set; }
    public int? LanguageId { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }

    public virtual Language Language { get; set; }
}

Next, implement few services to fetch languages and string resources from database. Here is an example of LanguageService

public class LanguageService : ILanguageService
{
    private readonly MyAppDbContext _context;

    public LanguageService(MyAppDbContext context)
    {
        _context = context;
    }

    public IEnumerable<Language> GetLanguages()
    {
        return _context.Languages.ToList();
    }

    public Language GetLanguageByCulture(string culture)
    {
       return _context.Languages.FirstOrDefault(x => 
           x.Culture.Trim().ToLower() == culture.Trim().ToLower());
    } 
}

Here is an example of a LocalizationService that has a method to return StringResource from database using the resource key.

public class LocalizationService : ILocalizationService
{
    private readonly MyAppDbContext _context;

    public LocalizationService(MyAppDbContext context)
    {
        _context = context;
    }

    public StringResource GetStringResource(string resourceKey, int languageId)
    {
        return _context.StringResources.FirstOrDefault(x => 
            x.Name.Trim().ToLower() == resourceKey.Trim().ToLower() 
            && x.LanguageId == languageId);
    }
}

Next step is to configure ASP.NET Core Localization according to the guidelines available in official Microsoft docs. Once everything is setup, you can create a method e.g. Localize to read localized strings. To use this method in multiple Controllers, this method can be defined in a BaseController class.

public class BaseController : Controller
{
    private readonly ILanguageService _languageService;
    private readonly ILocalizationService _localizationService;

    public BaseController(ILanguageService languageService, ILocalizationService localizationService)
    {
        _languageService = languageService;
        _localizationService = localizationService;
    }

    public HtmlString Localize(string resourceKey, params object[] args)
    {
        var currentCulture = Thread.CurrentThread.CurrentUICulture.Name;

        var language = _languageService.GetLanguageByCulture(currentCulture);
        if (language != null)
        {
            var stringResource = _localizationService.GetStringResource(resourceKey, language.Id);
            if (stringResource == null || string.IsNullOrEmpty(stringResource.Value))
            {
                return new HtmlString(resourceKey);
            }

            return new HtmlString((args == null || args.Length == 0)
                ? stringResource.Value
                : string.Format(stringResource.Value, args));
        }

        return new HtmlString(resourceKey);
    }
}

Using this Localize method, reading localized strings is as easy as the following example.

public IActionResult Index()
{
    ViewData["Title"] = Localize("customer.page.create.title");

    return View();
}

Upvotes: 1

Related Questions