且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ASP.NET Core 3.1 MVC中的本地化

更新时间:2023-02-15 13:00:28

问题1:与此相关的问题(options.RequestCultureProviders = new [] {new RouteDataRequestCultureProvider {IndexOfCulture = 1,IndexofUICulture = 1}};)它表示RequestCultureProviders没有IndexofUICulture ...

下载
Index.cshtml:

测试屏幕截图:


ASP.NET中的全球化和本地化核心
向ASP.NET Core应用程序添加本地化
如何在ASP.NET Core Web API中使用本地化

I'm trying to add localization to my ASP.NET Core 3.1 MVC project, unfortunately I could not find any article or tutorial that shows how to do it in an easy way.

Each and everyone is having some issues that I could not understand.

Could anyone please show me an easy way to do this? ok, I tried to do syncfusion.com/blogs/post/… but I faced an issue with this (options.RequestCultureProviders = new[] { new RouteDataRequestCultureProvider { IndexOfCulture = 1, IndexofUICulture = 1 } };) it says that RequestCultureProviders doesn't have IndexofUICulture......

I have reached this level:

    @using Microsoft.AspNetCore.Localization
@using Microsoft.Extensions.Localization 
@using System.Resources 
@model Index
@inject IStringLocalizer<Index> localizer 
@inject IHtmlLocalizer<Index> htmlLocalizer
@{
    ViewData["Title"] = "M-POS";
    //Microsoft.AspNetCore.Localization.IRequestCultureFeature requestCultureFeature;
    var requestCulture = CultureInfo.CurrentCulture;
    

}
    <div class="text-center">
        <h1 class="display-4">@localizer["Welcome"]</h1>
        <p>@localizer["Learn"]</p>


        <table class="table culture-table">
            <tr>
                <td style="width:50%;">Culture</td>
                <td>@requestCulture.DisplayName {@requestCulture.Name}</td>
            </tr>
            <tr>
                <td>UI Culture</td>
                <td>@requestCulture.Name</td>
            </tr>
            <tr>
                <td>UICulture Parent</td>
                <td>@requestCulture.Parent</td>
            </tr>
            <tr>
                <td>Date</td>
                <td>@DateTime.Now.ToLongDateString()</td>
            </tr>
            <tr>
                <td>Currency</td>
                <td>
                    @(12345.00.ToString("c"))
                </td>
            </tr>
            <tr>
                <td>Currency</td>
                <td>
                    @(12345.00.ToString("c"))
                </td>
            </tr>
            <tr>
                <td>Number</td>
                <td>
                    @(123.45m.ToString("F2"))
                </td>
            </tr>
        </table>
    </div>

and then I have a folder called Resources inside that folder I have a file called Resource.resx and Resource.en-US.resx and the StartUp.cs file is like that:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using POS3.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Models;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Razor;
using System.Globalization;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Localization.Routing;
using Microsoft.AspNetCore.Routing;
using Microsoft.CodeAnalysis.Options;

using Microsoft.AspNetCore.Http;
using System.Xml.Linq;

namespace POS3
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
              options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddDefaultIdentity<UserAccount>()
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddRazorPages();
            //localization startup

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddLocalization(options => options.ResourcesPath = "Resources");
            services.AddMvc().AddViewLocalization();
            services.AddMvc()
            .AddViewLocalization(options => options.ResourcesPath = "Resources")
            .AddDataAnnotationsLocalization();

            

            services.Configure<RequestLocalizationOptions>(options =>
            {
                var supportedCultures = new[]
                 {
                    
                    new CultureInfo("ar-SA"),
                    new CultureInfo("en-US")
                };
                options.DefaultRequestCulture = new RequestCulture("en-US");
                options.SupportedCultures = supportedCultures;
                options.SupportedUICultures = supportedCultures;
            });

            //services.Configure<RequestLocalizationOptions>(options =>
            //{
            //    var supportedCultures = new[]
            //    {
            //    new CultureInfo("en-US"),
            //    new CultureInfo("ar-SA"),
            //    new CultureInfo("es"),
            //};

            //    options.DefaultRequestCulture = new RequestCulture("en-US");
            //    options.SupportedCultures = supportedCultures;
            //    options.SupportedCultures = supportedCultures;
            //    //options.RequestCultureProviders = new[] { new RouteDataRequestCultureProvider { IndexOfCulture = 1, IndexOfCulture = 1 } };
            //});




            services.AddMvcCore();
            services.AddAuthorization(options => {
                options.AddPolicy("readonlypolicy",
                    builder => builder.RequireRole("Admin", "Manager", "Cashier", "User", "Super User"));
                options.AddPolicy("writepolicy",
                    builder => builder.RequireRole("Admin", "Manager", "Super User"));
            });

            

              


            services.Configure<IdentityOptions>(options =>
            {
                // Default Password settings.
                options.Password.RequireDigit = false;
                options.Password.RequiredLength = 6;
                options.Password.RequiredUniqueChars = 1;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequireLowercase = false;
            });

            services.AddControllersWithViews();
            services.AddRazorPages();
            services.AddControllers(config =>
            {
                
                var policy = new AuthorizationPolicyBuilder()
                                 .RequireAuthenticatedUser()
                                 .Build();
                config.Filters.Add(new AuthorizeFilter(policy));
            });

            services.Configure<PasswordHasherOptions>(options =>
            options.CompatibilityMode = PasswordHasherCompatibilityMode.IdentityV2
            );
            


            //services.AddSingleton<IEmailSender, EmailSender>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
           
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/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();

            //configer localization
            


            var localizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value;
            app.UseRequestLocalization(localizationOptions);

            app.UseAuthentication();
            app.UseAuthorization();           
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                
                endpoints.MapRazorPages();
            });

           
        }
    }
}

now I can't see resource.en-US.resx file values I think I'm missing something.

Q1: an issue with this (options.RequestCultureProviders = new[] { new RouteDataRequestCultureProvider { IndexOfCulture = 1, IndexofUICulture = 1 } };) it says that RequestCultureProviders doesn't have IndexofUICulture......

Download the samples you will find RouteDataRequestCultureProvider.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;

namespace LocalizationSampleSingleResxFile
{
    public class RouteDataRequestCultureProvider : RequestCultureProvider
    {
        public int IndexOfCulture;
        public int IndexofUICulture;

        public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
        {
            if (httpContext == null)
                throw new ArgumentNullException(nameof(httpContext));

            string culture = null;
            string uiCulture = null;

            culture = uiCulture = httpContext.Request.Path.Value.Split('/')[IndexOfCulture]?.ToString();

            var providerResultCulture = new ProviderCultureResult(culture, uiCulture);

            return Task.FromResult(providerResultCulture);
        }
    }
}

Q2: Change name of your resource

You already named en-US, so your resource file name must format with en-US.

Index.cshtml:

Screenshots of test:


Globalization and localization in ASP.NET Core
Adding Localisation to an ASP.NET Core application
How to Use Localization in an ASP.NET Core Web API