MVC MvcSiteMap Route
▌Scenario
In
the previous article: [MVC] MvcSiteMap with Dependency Injection, we successfully
created a menu with MvcSiteMap.
If
we define a custom route with extra route placeholders, such as
routes.MapRoute(
name: "Default",
url: "{lang}/{controller}/{action}/{id}",
defaults: new { lang = "Default", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
|
Which
{lang} is expected to have these values,
http://localhost:1410/EN/Home/Index
http://localhost:1410/CN/Home/Index
http://localhost:1410/ZH/Home/Index
However,
the problem is that we will always get the default value for {lang} in the
node’s url like the following picture from MvcSiteMap in
default!
What I expect
is to have the same {lang} value as the current url.
There are two
ways to get this job done, let’s take a look.
▋Related articles
▌Environment
▋Visual Studio 2017
▋MvcSiteMapProvider.MVC5
4.6.22
▋MvcSiteMapProvider.MVC5.DI.Unity
4.6.22
▌Implement
▋Method 1. Update MenuNodeProvider
While we create every node in MenuNodeProvider, we
also give every node a route value for key: "lang"
▋MenuNodeProvider.cs
DynamicNode dynamicNode = new DynamicNode()
{
//…
};
string lang = string.Empty;
CultureInfo ci =
System.Threading.Thread.CurrentThread.CurrentCulture;
if (ci != null)
{
switch (ci.Name.ToLower())
{
case "en-us":
lang = "EN";
break;
case "zh-cn":
lang
= "CN";
break;
default:
lang
= "ZH";
break;
}
}
dynamicNode.RouteValues.Add("lang", lang);
|
So that the
route value will be mapped to the url pattern’s placeholders: {lang}
▋Method 2. Update Display
template
First go to _Layout.cshtml
and find the following codes.
@Html.MvcSiteMap().Menu("BootstrapMenuHelperModel", false)
|
Open BootstrapMenuHelperModel.cshtml, we
will create a @Helper to display the
current route value for {lang}.
@helper LangValue()
{
var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;
string lang = "Default";
if (routeValues != null)
{
if
(routeValues.ContainsKey("lang"))
{
lang
= routeValues["lang"].ToString();
}
}
@lang;
}
|
Update the url
of link from
<a href="@url">
|
To
<a href="/@LangValue()@url">
|
Last,
make sure that in the custom route pattern, the placeholder: {lang}, DOES NOT
have a default value.
PS. If you set Area for the MVC website, update the Area’s route as well.
PS. If you set Area for the MVC website, update the Area’s route as well.
routes.MapRoute(
name: "Default",
url: "{lang}/{controller}/{action}/{id}",
defaults: new { lang = UrlParameter.Optional,
controller = "Home", action = "Index", id = UrlParameter.Optional }
);
|
▌Reference
沒有留言:
張貼留言