locked
How can I make the StatusCodePages support Localizer? RRS feed

  • Question

  • User1052024640 posted

    Here is the Configure:

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Error");
                    app.UseHttpsRedirection();
                }
    
                var SupportedCultures = new List<CultureInfo> {
                    new CultureInfo("en"),
                    new CultureInfo("zh-Hans"),
                    new CultureInfo("zh-Hant")
            };
                var options = new RequestLocalizationOptions
                {
                    DefaultRequestCulture = new RequestCulture("en"),
                    SupportedCultures = SupportedCultures,
                    SupportedUICultures = SupportedCultures
                };
                app.UseRequestLocalization(options);
                app.UseStaticFiles();
    
                app.UseStatusCodePagesWithReExecute("{culture}/StatusCode/{0}");
    
    
                var requestProvider = new RouteDataRequestCultureProvider();
                options.RequestCultureProviders.Insert(0, requestProvider);
    
                app.UseRouter(routes =>
                {
                    routes.MapMiddlewareRoute("{culture=en}/{*mvcRoute}", subApp =>
                    {
                        subApp.UseRequestLocalization(options);
                        subApp.UseRouting();
                        subApp.UseEndpoints(mvcRoutes =>
                        {
                            mvcRoutes.MapControllerRoute(
                                name: "default",
                                pattern: "{culture=en}/{controller=Home}/{action=Index}");
                            // map the .html suffix
                            mvcRoutes.MapControllerRoute(
                                name: "home.html",
                                pattern: "{culture=en}/{controller=Home}/{action}.html");
                        });
                    });
                });
            }

    And here is the StatusCodeController:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    
    namespace Test.Controllers
    {
        public class StatusCodeController : Controller
        {        
            [HttpGet("{culture}/StatusCode/{statusCode}")]
            public IActionResult Index(int statusCode)
            {
                return View(statusCode);
            }
        }
    }

    The Localizer works well.

    Whereas, when I navigate a URL which the page does not exist. It will only redirect to the default language 404Page, such as http://localhost:5009/en/StatusCode/404

    I have added the culture property inside the app.UseStatusCodePagesWithReExecute but it seems no works.

    How can I solve this? Thank you.

    Tuesday, September 17, 2019 9:05 AM

Answers

  • User1052024640 posted

    It works now. However, it needs to add the method inside every controller. 

    I remembered that the URL also store the Culture in my project, so I modified the code like this:

     app.UseStatusCodePages(async context =>
    {
    await Task.Run(() =>
    {
    string currentCulture = "";
    if (context.HttpContext.Request.Path.Value.Split('/').Length < 2)
    {
    currentCulture = "en";
    }
    else
    {
    string LanguageGet = context.HttpContext.Request.Path.Value.Split('/')[1];
    currentCulture = SupportedCultures.Find(X => X.Name == LanguageGet) == null ? "en" : SupportedCultures.Find(X => X.Name == LanguageGet).Name;
    }
    var redirectPath = "/" + currentCulture + "/StatusCode/" + context.HttpContext.Response.StatusCode;
    context.HttpContext.Response.Redirect(redirectPath);
    });
    });

    It works. Aha.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, September 19, 2019 10:39 AM

All replies

  • User1634355159 posted

    Hi mywatermelon,

    You could not use the placeholder "{culture}" directly in the UseStatusCodePagesWithReExecute() method. You need to add a new StatusCodePages middleware to the pipeline to get the current culture.

    This is the method of redirection:

     app.UseStatusCodePages(async context =>
                {
                    var currentCulture = CultureInfo.CurrentCulture.Name;
                    var redirectPath = "/" + currentCulture + "/StatusCode/" + context.HttpContext.Response.StatusCode;
                    context.HttpContext.Response.Redirect(redirectPath);
                });

    This is the method of rewriting:

     app.UseStatusCodePages(async context =>
                {
                    var currentCulture = CultureInfo.CurrentCulture.Name;
                    var newPath = "/" + currentCulture + "/StatusCode/" + context.HttpContext.Response.StatusCode;
                    context.HttpContext.Request.Path = newPath;
                    await context.Next(context.HttpContext);
                });

    Best Regards ,

    Lewis Lu

    Thursday, September 19, 2019 6:40 AM
  • User1052024640 posted

    No, it doesn't work.

    I added a breakpoint in the Visual Studio. When running a page which not exists, 

    var currentCulture = CultureInfo.CurrentCulture.Name;

    The codes above always get "en" even the URL is 'http://localhost:5009/zh-Hans/product/555.html' which the Localizer is zh-hans.

    Thursday, September 19, 2019 8:07 AM
  • User1634355159 posted

    Hi mywatermelon,

    Are you missing the method which you changed your CurrentCulture in you project ? here is my way,I put it in the index method of the home controller.

    public IActionResult Index()
            {
                Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(new RequestCulture("zh-Hant")),
                new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) });
                return View();
            }

    Best Regards ,

    Lewis Lu

    Thursday, September 19, 2019 10:01 AM
  • User1052024640 posted

    It works now. However, it needs to add the method inside every controller. 

    I remembered that the URL also store the Culture in my project, so I modified the code like this:

     app.UseStatusCodePages(async context =>
    {
    await Task.Run(() =>
    {
    string currentCulture = "";
    if (context.HttpContext.Request.Path.Value.Split('/').Length < 2)
    {
    currentCulture = "en";
    }
    else
    {
    string LanguageGet = context.HttpContext.Request.Path.Value.Split('/')[1];
    currentCulture = SupportedCultures.Find(X => X.Name == LanguageGet) == null ? "en" : SupportedCultures.Find(X => X.Name == LanguageGet).Name;
    }
    var redirectPath = "/" + currentCulture + "/StatusCode/" + context.HttpContext.Response.StatusCode;
    context.HttpContext.Response.Redirect(redirectPath);
    });
    });

    It works. Aha.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, September 19, 2019 10:39 AM