Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

The default MVC 3 route config is
{controller}/{action}/{id}
My NEWS application structure is like

/News/Latest10
/News/Critical/10June2013
/Entertainment/Latest10

Bold ones being controller, italics as actions, and normal text are optional params.
Now I want to add new variable, language, into the url structure.

It should be like
/en/News/Latest10
/ja/News/Critical/10June2013
/de/Entertainment/Latest10

I would like to know how to access this language variable in the controller. Is it possible?

Thanks

share|improve this question

1 Answer 1

up vote 2 down vote accepted

To meet your needs change the Route config to:

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

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

The two key parts are the route itself, {language}/{controller}/{action}/{id} and the constraint part, new {language=new LanguageConstraint()}.

The first part will select the {language} part as a variable (default being en for now) to the controller. The controller signature:

 public ActionResult Index(string language) {

will pick up the new language variable. Since adding language to each and every controller could seem cumbersome you could create a ViewModelBase class to passed to every controller with a property that contains the language value, which every subsequent View Model class inherits from.

Without a constraint the route pattern would pick up all values in the url for the language part and writing a Regex expression to match all wanted language values would be tedious, I think it's easier to write an IRouteConstraint based class similar to the following:

public class LanguageConstraint : IRouteConstraint{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
                      RouteDirection routeDirection) {

        //create accepted lanaguages collection from somewhere.
        string[] languageArray = new[]{"en","jp", "de"};

        string language = values["language"].ToString();

        if (string.IsNullOrEmpty(language))
            return false;

        return languageArray.FirstOrDefault(l=>l.Equals(language,StringComparison.InvariantCultureIgnoreCase)) != null;
    }
}

Simply it creates a list of known language values and check the provided language value against that list. If it doesn't exist false is returned and a 404 is thrown.

share|improve this answer
1  
+1 a nicely explained answer with focus on constrains as the second and default route is also present –  Parv Sharma Jun 16 '13 at 0:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.