using XLocalizer.DB;// Register translation service
services.AddHttpClient<ITranslator,MyMemoryTranslateService>();
services.AddRazorPages().AddXDbLocalizer<ApplicationDbContext,MyMemoryTranslate>(ops =>{ ops.AutoAddKeys =true; ops.AutoTranslate =true;});
User secrets
MyMemory offers a free or paid subscriptions, and depending on your setup it may require an Api key to be provided, for more details see MyMemoryTranslateService.
XLocalizer has built-in caching enabled by default. Caching helps to speedup the retriving of localized resources. But, it is recommended to switch caching off during development to avoid caching values that are subject to change frequently.
ops.UseExpressMemoryCache =false;
Localization stores setup
DB localization requires two stores in the database; one for the cultures, and one for the resources. The default models are already defined in XLocalizer.DB.Models, we only need to add them to our context:
Open ApplicationDbContext.cs file and add below setup:
using XLocalizer.DB.Models;publicclassApplicationDbContext:IdentityDbContext{publicApplicationDbContext(DbContextOptions<ApplicationDbContext>options):base(options){}// Cultures table will hold the supported cultures entitiespublicDbSet<XDbCulture> XDbCultures {get;set;}// All resources will be saved in this tablepublicDbSet<XDbResource> XDbResources {get;set;}protectedoverridevoidOnModelCreating(ModelBuilderbuilder){
builder.Entity<XDbResource>().HasKey(r => r.ID);
builder.Entity<XDbResource>().HasIndex(r =>new{ r.CultureID, r.Key }).IsUnique();
builder.Entity<XDbResource>().HasOne(t => t.Culture).WithMany(c => c.Translations asIEnumerable<XDbResource>).OnDelete(DeleteBehavior.Cascade);
builder.SeedCultures();
builder.SeedResourceData();base.OnModelCreating(builder);}}
If you want to add more tables for resources similar to XDbResource, just implement IXDbResource interface and add the relevant setup to ApplicationDbContext.
Just for starting with some data, create an extension method to seed initial data:
publicstaticclassSeedXLocalizerValues{publicstaticvoidSeedCultures(thisModelBuildermodelBuilder){// Seed initial data for localization stores
modelBuilder.Entity<XDbCulture>().HasData(new XDbCulture {IsActive=true,IsDefault=true,ID="en",EnglishName="English"},new XDbCulture {IsActive=true,IsDefault=false,ID="tr",EnglishName="Turkish"},new XDbCulture {IsActive=true,IsDefault=false,ID="ar",EnglishName="Arabic"});}publicstaticvoidSeedResourceData(thisModelBuildermodelBuilder){
modelBuilder.Entity<XDbResource>().HasData(new XDbResource {ID=1,Key="Welcome",Value="Hoşgeldin",CultureID="tr",IsActive=true,Comment="Created by XLocalizer"});}}
ApplicationDbContext LifeTime
Asp.Net Core expects localization services to be added as singleton, so we have to change the ApplciationDbContext lifetime to avoid scoped and singleton conflicts.
This package provides a ready made user panel to manage XLocalizer DB resources. After installing the package simply use below links to access the management panel.
The panel provides below editors for cultures and resources:
Full startup code for DB setup
using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Identity;using Microsoft.AspNetCore.Hosting;using Microsoft.EntityFrameworkCore;using XmlLocalizationSample.Data;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;using XLocalizer.Translate;using XLocalizer;using XLocalizer.DB;using System.Globalization;using XLocalizer.Routing;using XLocalizer.Translate.MyMemoryTranslate;using DbLocalizationSample.LocalizationResources;namespaceDbLocalizationSample{publicclassStartup{publicStartup(IConfigurationconfiguration){Configuration=configuration;}publicIConfigurationConfiguration{get;}// This method gets called by the runtime. Use this method to add services to the container.publicvoidConfigureServices(IServiceCollectionservices){// Change DbContext lifetime to transient.// By default it is scoped, but this conflicts with singleton lifetime of localization services.
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")),
ServiceLifetime.Transient, ServiceLifetime.Transient);
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount =true).AddEntityFrameworkStores<ApplicationDbContext>();
services.Configure<RequestLocalizationOptions>(ops =>{varcultures=new CultureInfo[]{new CultureInfo("en"),new CultureInfo("tr"),new CultureInfo("ar")}; ops.SupportedCultures =cultures; ops.SupportedUICultures =cultures; ops.DefaultRequestCulture =new Microsoft.AspNetCore.Localization.RequestCulture("en");// Optional: add custom provider to support localization based on route value {culture} ops.RequestCultureProviders.Insert(0,new RouteSegmentRequestCultureProvider(cultures));});// Optional: To enable online translation register one or more translation services
services.AddHttpClient<ITranslator,MyMemoryTranslateService>();
services.AddRazorPages()// Optional: Add {culture} route template to all razor pages routes e.g. /en/Index.AddRazorPagesOptions(ops =>{ ops.Conventions.Insert(0,new RouteTemplateModelConventionRazorPages());})// Add XLocalization with and specify a service for handling translation requests.AddXDbLocalizer<ApplicationDbContext,MyMemoryTranslateService>(ops =>{// Resources folder path required in case of // exporting db resources to resx resource files. ops.ResourcesPath ="LocalizationResources"; ops.AutoAddKeys =true; ops.AutoTranslate =true;});}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){if(env.IsDevelopment()){
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();}else{
app.UseExceptionHandler("/Error");// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseRequestLocalization();
app.UseEndpoints(endpoints =>{ endpoints.MapRazorPages();});}}}