Setup:
I am using ASP.NET MVC 4, with mvcSiteMapProvider to manage my menus.
I have a custom menu constructor that evaluates whether a node is in the current branch (i.e. if it SiteMap.CurrentNodeis either CurrentNode or CurrentNode is nested in it). The code is below, but essentially checks the URL of each node and compares it with the URL of the current level, through the "family tree" currentnodes.
CurrentBranch is used by my customizable menu designer to add a class that highlights menu items in CurrentBranch.
Problem:
My custom menu is working fine, but I found that it mvcSiteMapProviderapparently doesn't rate url CurrentNodeaccording:
When two nodes point to the same action and differ only in the action parameter, SiteMap.CurrentNode does not seem to use the correct route (it ignores the distinguishing parameter and by default uses the first route that displays the action defined in node).
Example problem:
In the application I have Members.
The member has a field MemberStatusthat can be "Unprocessed", "Active" or "Inactive". To change the MemberStatus element, I have ProcessMemberControllerin an area called Admin. Processing is performed using an action Processon ProcessMemberController.
mvcSiteMap , BOTH Process. - alternate ( ), "" "":
:
<mvcSiteMapNode title="Process" area="Admin" controller="ProcessMembers" action="Process" alternate="Unprocessed" />
<mvcSiteMapNode title="Change Status" area="Admin" controller="ProcessMembers" action="Process" alternate="Processed" />
( , , , - ):
context.MapRoute(
"Process_New_Members",
"Admin/Unprocessed/Process/{MemberId}",
new { controller = "ProcessMembers",
action = "Process",
alternate="Unprocessed",
MemberId = UrlParameter.Optional }
);
context.MapRoute(
"Change_Status_Old_Members",
"Admin/Members/Status/Change/{MemberId}",
new { controller = "ProcessMembers",
action = "Process",
alternate="Processed",
MemberId = UrlParameter.Optional }
);
:
Html.ActionLink URL:
@Html.ActionLink("Process", MVC.Admin.ProcessMembers.Process(item.MemberId, "Unprocessed")
// Output (alternate="Unprocessed" and item.MemberId = 12): Admin/Unprocessed/Process/12
@Html.ActionLink("Status", MVC.Admin.ProcessMembers.Process(item.MemberId, "Processed")
// Output (alternate="Processed" and item.MemberId = 23): Admin/Members/Status/Change/23
, .
:
, , .. /Admin/Members/Status/Change/47, alternate = "Processed" MemberId 47.
CurrentBranch (. ), , SiteMap.CurrentNode :
PreviousSibling: null
Provider: {MvcSiteMapProvider.DefaultSiteMapProvider}
ReadOnly: false
ResourceKey: ""
Roles: Count = 0
RootNode: {Home}
Title: "Process"
Url: "/Admin/Unprocessed/Process/47"
.., url/Admin/Members/Status/Change/47, SiteMap.CurrentNode.Url /Admin/Unprocessed/Process/47. .., alternate .
CurrentBranch:
public static List<SiteMapNode> CurrentBranch
{
get
{
List<SiteMapNode> currentBranch = null;
if (currentBranch == null)
{
SiteMapNode cn = SiteMap.CurrentNode;
SiteMapNode n = cn;
List<SiteMapNode> ln = new List<SiteMapNode>();
if (cn != null)
{
while (n != null && n.Url != SiteMap.RootNode.Url)
{
ln.Add(n);
n = n.ParentNode;
}
ln.Add(SiteMap.RootNode);
ln.Reverse();
}
currentBranch = ln;
}
return currentBranch;
}
}
:
?
Html.ActionLlink, , SiteMap.CurrentNode, . , SiteMap.CurrentNode .