3

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

1 Answer 1

2

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.

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

1 Comment

+1 a nicely explained answer with focus on constrains as the second and default route is also present

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.