3

My problem: Everything works fine when I use links like:

http://localhost:12816/en/Statistic/Reports

But when I remove "/en" - I get application error:

"Server Error in '/' Application. The resource cannot be found."

I have several Resource files for different languages. I want my application to use default language (english) when user requests links without any language identification.

E.g. I want these links to do exactly the same:

http://localhost:12816/Statistic/Reports
http://localhost:12816/en/Statistic/Reports

Btw, I've noticed that when I request short links without language - all works fine:

http://localhost:12816/Statistic/

But when link is deeper, I get and error

I think the problem is in routing, but I'm newbie to routes, so please help me :)

PS: I've tried like this, but it didn't work:

routes.MapRoute("Default", "{lang}/{controller}/{action}/{id}",                 
        new{
            lang = "en",
            controller = "Home",
            action = "Index",
            id = UrlParameter.Optional,
        });

routes.MapRoute("Default no language", "{controller}/{action}/{id}",
        new
        {
            controller = "Home",
            action = "Index",
            id = UrlParameter.Optional
        });

1 Answer 1

5

You could try removing the default "lang" value from the no language route, and adding a regex constant to the language route (For example allowing culture names like "en" or "en-US", check this question about a regex for culture names):

routes.MapRoute(
    name: "Default lang",
    url: "{lang}/{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    constraints: new { lang = @"[a-z]{2,3}(?:-[A-Z]{2,3})?" }
);

routes.MapRoute(                
    name: "Default no language",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

If you don't add a constraint for the lang parameter, an url like /Statistics/Reports will always match the language route (because its defined first) with the wrong parameters lang=Statistics, controller=Report, action=Index

So with this route configuration, you will get these results:

  • / -> routed to Home/Index, there is NOT a route value for lang
  • /Home -> routed to Home/Index, there is NOT a route value for lang
  • /Home/About -> routed to Home/About, there is NOT a route value for lang
  • /en -> routed to Home/Index, there is a route value with lang=en
  • /en/Home -> routed to Home/Index, there is a route value with lang=en
  • /en/Home/About -> routed to Home/About, there is a route value with lang=en

Then you can use the lang route value on any logic involved in getting the resources, and when the value is missing from the route data you could treat it as the default language.

For example, let's say you have created a global filter that will set the CurrentCulture and CurrentUICulture on the thread based on this route parameter. You could leave them with their default values (the ones configured on your server or web.config) when no lang was provided, otherwise override them based on the lang parameter:

public class InitializeCultureAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.RouteData.Values.ContainsKey("lang")) return;

        var culture = filterContext.RouteData.Values["lang"] as string;
        if (String.IsNullOrEmpty(culture)) return;

        var cultureInfo = CultureInfo.GetCultureInfo(culture);
        Thread.CurrentThread.CurrentCulture = cultureInfo;
        Thread.CurrentThread.CurrentUICulture = cultureInfo;                
    }
}

PS. I don't mean you should use this attribute, I just want to show an example of how you could deal with not having a lang value in the route data. So with the routes above you should be able to adapt your logic dealing with resources, by looking at the lang parameter in the route data (although I guess you may want to set the CurrentUICulture in that case!)

Hope this helps!

Sign up to request clarification or add additional context in comments.

1 Comment

Great it works for me too I was same issue for default lang. now it resolved by ActionFilterAttribute inherit class as you mentioned above... I appreciate your article..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.