MVC - changing part of URL in a link
I have a site that supports localization. I would like to be able to switch between English and French.
Let say the user is currently at URL: http://www.example.com/**en**/Home
I would like to redirect to: http://www.example.com/**fr**/Home
If the user click on a "French" link how to change the URL part to "fr" yet not change the "Home" part of the URL (basically I want preserve the current location of the user)
Hope my question makes sense! I'm probably missing something very basic?
EDIT: Kind of found a solution.
<%= Html.ActionLink("Français", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { culture = "fr" }, null)%>
<%= Html.ActionLink("English", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { culture = "en" }, null)%>
This maintains 开发者_如何学Pythonthe action/controller of the current URL. Maybe there's a cleaner solution?
In your Global.asax
routes.MapRoute(
name: "LocalizedRoute",
url: "{language}/{controller}/{action}/{id}",
defaults:
new
{
language= "fr",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
},
constraints: new { language= @"[a-z]{2}" });
And you can have access to the language with the variable language in your controller
To generate a link:
<%= Html.ActionLink("French", ViewContext.RouteData.Values["action"], new { language = "fr" }) %>
And you can make a base class controller with this property:
public string Language { get { return this.Routedata["language"]; } }
I made a extension for RouteValueDictionary to solve this problem:
public static RouteValueDictionary SetValue(this RouteValueDictionary dictionary, string key, object value)
{
RouteValueDictionary rvd = new RouteValueDictionary(dictionary);
rvd[key] = value;
return rvd;
}
Now you can use this as follow in the html template:
<div id="head">
@Html.RouteLink("DE", ViewContext.RouteData.Values.SetValue("language", "de")) |
@Html.RouteLink("FR", ViewContext.RouteData.Values.SetValue("language", "fr")) |
@Html.RouteLink("IT", ViewContext.RouteData.Values.SetValue("language", "it")) |
@Html.RouteLink("EN", ViewContext.RouteData.Values.SetValue("language", "en"))
</div>
The extension don't modifiy the RoutData.Values collection, it makes a copy and you can override the desired value.
I would suggest making the urls in this format:
http://www.mysite.com/Home/en
Then you can make actions as simple as this:
<%= Html.ActionLink("Francais", "Home", "MyController", new { id = "fr" }), null %>
<%= Html.ActionLink("English", "Home", "MyController", new { id = "en" }), null %>
Then in your controller have an action:
public ActionResult Home(string id)
{
if(id == "en"){ // do something }
else if(id == "fr") { // do something else }
return View();
}
Global.asax Route
routes.MapRoute(
"HomeLanguageRoute", // Route name
"MyController/Home/{id}", // URL with parameters
new { controller = "MyController", action = "Home", id = "" } // Parameter defaults
);
精彩评论