ASP.NET (MVC) Routes Internationalization

I was looking for a solution for internationalizing / localizing routes on the ASP.NET MVC website. I stumbled upon a blog post Translating Routes (ASP.NET MVC and Webforms) from Maarten Balliauw. It is a very nice solution that works great - until the view has Html.RenderAction("...") .

He basically introduces TranslatedRoute , inheriting from System.Web.Routing.Route , than translating using a dictionary with on-the-fly translation.

Any idea why this happens differently when calling Html.RenderAction("...") ? It also seems that if an error occurs only if the action to be displayed is in the same controller.

And here is the exact error:

'Controller for path' / MyTranslatedControllerName 'not found or does not implement IController.

Update:

Here is my route configuration (taken from the Maarten project example, added routes for Contact, which is partial for visualization):

  public static void RegisterRoutes(RouteCollection routes) { CultureInfo cultureEN = CultureInfo.GetCultureInfo("en-US"); CultureInfo cultureDE = CultureInfo.GetCultureInfo("de-DE"); CultureInfo cultureFR = CultureInfo.GetCultureInfo("fr-FR"); DictionaryRouteValueTranslationProvider translationProvider = new DictionaryRouteValueTranslationProvider( new List<RouteValueTranslation> { new RouteValueTranslation(cultureEN, "Home", "Home"), new RouteValueTranslation(cultureEN, "About", "About"), new RouteValueTranslation(cultureEN, "Contact", "Contact"), new RouteValueTranslation(cultureDE, "Home", "Home"), new RouteValueTranslation(cultureDE, "About", "About"), new RouteValueTranslation(cultureDE, "Contact", "Kontakt"), new RouteValueTranslation(cultureFR, "Home", "Demarrer"), new RouteValueTranslation(cultureFR, "About", "Infos"), new RouteValueTranslation(cultureFR, "Contact", "Contact") } ); routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapTranslatedRoute( "TranslatedRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "" }, new { controller = translationProvider, action = translationProvider }, true ); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = "" } // Parameter defaults ); 
+6
source share
2 answers

This will depend on the configuration of your route. Can you share it?

EDIT: It seems that the RenderAction method uses "GetVirtualPath" on the route to determine the URL for MvcHandler. However, it does not call the GetRouteData method.

There is a method for detecting this: routeData.DataTokens ["ParentActionViewContext"] The problem is that TranslatedRoute is already in late contact with this ...

In short: I'm afraid this is not possible due to the current implementation of ChildActionExtensions.ActionHelper in System.Web.Mvc ...

I have a (dirty, presumptuous) workaround (which can also be wrapped in a custom RenderAction () method): - In your opinion, do the following:

 <% RouteData.DataTokens.Add("GoingToRenderChildAction", true); %> <% Html.RenderAction("Contact", "Home"); %> <% RouteData.DataTokens["GoingToRenderChildAction"] = false; %> 

Razor Syntax:

 @{ ViewContext.RequestContext.RouteData.DataTokens.Add("GoingToRenderChildAction", true); } @Html.Action("Action", "Controller" ) @{ ViewContext.RequestContext.RouteData.DataTokens["GoingToRenderChildAction"]=false; } 

In TranslatedRoute.cs GetVirtualPath add the following as the first statement:

 if(requestContext.RouteData.DataTokens.ContainsKey("GoingToRenderChildAction") && (bool)requestContext.RouteData.DataTokens["GoingToRenderChildAction"] == true) { return base.GetVirtualPath(requestContext, values); } 

This will work, but may have unwanted side effects.

+4
source

In your view (Razor syntax, VB):

 @Html.Action("Index", "Home", New With {.childAction = True}) 

Then in TranslatedRoute.cs GetVirtualPath as the first statement:

 if (values.ContainsKey("childAction") && (bool)values["childAction"] == true) { return base.GetVirtualPath(requestContext, values); } 

This method is much easier and only for the desired action.

0
source

Source: https://habr.com/ru/post/889663/


All Articles