1

I'm trying to do something like what is microsoft used for docs site. for example when I enter the link below in addressbar, microsoft docs site redirects me to default cultured link as what is in second link.

first link: https://learn.microsoft.com/aspnet/core/fundamentals/localization?view=aspnetcore-2.2 Second Link: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.2

I go step by step with this article (https://joonasw.net/view/aspnet-core-localization-deep-dive) and project successfully runs and I can change culture by calling urls like

localhost:5001/tr-TR/home/index ({culture}/[controller]/[action]) 

but when I try to route to

localhost:5001/home/index (without culture route value)

I get error 404.

What I need is to route the above link into some shared controller action and then redirect it to

localhost:5001/{defaultculture}/home/index

Thank you in advance.

mesut
  • 2,099
  • 3
  • 23
  • 35

2 Answers2

0

You need to change your route. In example below when user enter to localhost:5001/home/index will be redirected to RedirectToCulture action in Home controller. Now you can read parametrs (or not) and redirect with deafult culture

routes.MapRoute(
    name: "default1",
    template: "{culture:required}/{controller:required}/{action:required}/{id?}",
    defaults: new { culture = "en-US", controller = "Home", action = "Index" });

routes.MapRoute(
    name: "default2",
    template: "{stringController?}/{stringAction?}/{id?}",
    defaults: new { controller = "Home", action = "RedirectToCulture" });
J. Doe
  • 2,651
  • 1
  • 13
  • 31
  • Hi J. Doe thanks for answer, will this work with attribute routing also? for example when I have a [Route("ShowSales")] on top of HomeController's Index Action, will this work? I'm going to try by the way – mesut Dec 13 '18 at 10:51
  • Tried, and fail, we should always add {ui-culture} before every route attribute. – mesut Dec 13 '18 at 11:27
  • Then add in `RedirectToCulture` action redirect to action with culture (`return RedirectToAction("Index", new { culture = "en-US" });`). Thats a point of this routing – J. Doe Dec 13 '18 at 12:21
0

For https://learn.microsoft.com, it used URL Redirect feature to implement route https://learn.microsoft.com/aspnet/core/fundamentals/localization?view=aspnetcore-2.2 to https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.2. If you check the request log for https://learn.microsoft.com/aspnet, you will find for the first request, it returns response with Status Code: 301 and then return https://learn.microsoft.com/en-us/aspnet.

For your requirement, if you only need localhost:5001/home/index to return view from localhost:5001/en-us/home/index without the url change to localhost:5001/en-us/home/index. You could try

var localizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value;
var requestProvider = new RouteDataRequestCultureProvider();
localizationOptions.RequestCultureProviders.Insert(0, requestProvider);
app.UseRouter(routes =>
{
    routes.MapMiddlewareRoute("{culture=en-US}/{*mvcRoute}", subApp =>
    {
        subApp.UseRequestLocalization(localizationOptions);

        subApp.UseMvc(mvcRoutes =>
        {
            mvcRoutes.MapRoute(
                name: "default",
                template: "{culture=en-US}/{controller=Home}/{action=Index}/{id?}");
        });
    });

});

If you need the URL the same as localhost:5001/en-us/home/index, you also need to take redirect action.

app.Use(async (context, next) =>
{
    await next.Invoke();
    if (context.Response.StatusCode == StatusCodes.Status404NotFound)
    {
        context.Response.Redirect(@"/en-us/Home/Index", true);
    }
});

app.UseRouter(routes =>
{
    routes.MapMiddlewareRoute("{culture}/{*mvcRoute}", subApp =>
    {
        subApp.UseRequestLocalization(localizationOptions);

        subApp.UseMvc(mvcRoutes =>
        {
            mvcRoutes.MapRoute(
                name: "default",
                template: "{culture}/{controller=Home}/{action=Index}/{id?}");
        });
    });

});
Edward
  • 28,296
  • 11
  • 76
  • 121
  • Hi Tao, Thank you for your answer, but I want to redirect every request that is received without culture, to same request URL but added default culture to it. – mesut Dec 13 '18 at 10:49
  • @mesut You could generate the Redirect path based on your own requirement on `context.Response.Redirect(@"/en-us/Home/Index", true);`. – Edward Dec 14 '18 at 02:11