AttributeRouting icon indicating copy to clipboard operation
AttributeRouting copied to clipboard

ConstrainTranslatedRoutesByCurrentUICulture is not working

Open mdmoura opened this issue 10 years ago • 2 comments

Following the AttributeRouting.NET localization example I have:

routes.MapAttributeRoutes(config => {
  config.ConstrainTranslatedRoutesByCurrentUICulture = true;
  config.CurrentUICultureResolver = (httpContext, routeData) => {
    return (string)routeData.Values["culture"] ?? Thread.CurrentThread.CurrentUICulture.Name;
  };
  config.UseRouteHandler(() => new CultureRouteHandler());
});

The logic to define the culture is in the CultureRouteHandler:

public class CultureRouteHandler : MvcRouteHandler {
  protected override IHttpHandler GetHttpHandler(RequestContext context) {
    var c = context.RouteData.Values["culture"];
    // Remaining code
  } 
}

And the HomeController is the following:

[RoutePrefix("{culture?}")]
public partial class HomeController : WebController {
  [GET("")]
  public virtual ActionResult Index() { }
}

I added a breakpoint inside the GetHttpHandler method in the CultureRouteHandler.

When I start the site this breakpoint is not fired so the default culture becomes "en-US".

This way on the start of the site my logic to choose the culture does not run.

In the next requests, e.g. navigating through pages, the GettHttpHandler fires.

Is this a bug or is expected to work like this? How can I solve this?

Thank You

mdmoura avatar Oct 12 '13 21:10 mdmoura

I think there is an error on AR documentation or maybe in AR itself.

When a parameter is optional the key is being added to the route dictionary. This means its value is empty, e.g., equal to UrlParameter.Optional ...

AR documentation has the following (the casting will not work when the UrlParameter is Optional): return (string)routeData.Values["culture"] ?? Thread.CurrentThread.CurrentUICulture.Name;

The solution to fire the CultureRouteHandler for the nullable culture in the home page is:

config.CurrentUICultureResolver = (context, data) => {
      var value = data.Values["culture"];
      if (value == null) {
        return Thread.CurrentThread.CurrentUICulture.Name;
      } else if (value == UrlParameter.Optional) {
        return "";
      } else 
        return (String)value;
}

Now the CultureHandler is fired even on the site start ... And in the Culture Handler I have:

protected override IHttpHandler GetHttpHandler(RequestContext context) {
  String culture = context.RouteData.Values[_culture] as String;
  if (culture == null) {
     // remaining code
}

This is now working ... But am I missing something or is there a bug in AR?

Thank You, Miguel

mdmoura avatar Oct 14 '13 22:10 mdmoura

The solution I presented works fine with only one problem:

config.x.ConstrainTranslatedRoutesByCurrentUICulture = true;

This has no effect ... I needed to add:

config.AddDefaultRouteConstraint(@"^culture$", new RegexRouteConstraint(@"(?i:^(pt|en)$)"));

Could someone look at this thread so we arrive to a working localization solution?

mdmoura avatar Oct 22 '13 09:10 mdmoura