-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Won't differentiate paths based on different attributes #332
Comments
The reason it seemed to work in prior versions was because it was attempting to match on both route values and URL. This caused some quirky behavior that led to matches in incorrectly configured applications and tended to break when using route values that change per request because it was then comparing a URL that was cached at startup to one that could change dynamically. That bug had been fixed, but it also meant that query string values were no longer being taken into account. I modified the behavior so now it takes into account query string values with matching keys that are configured in the node. Route values take precedence over query string values in cases where both of them are in the request. That said, it won't work exactly like it was in the original example. In order for it to compare the "something" parameter, it needs to be added as a key to the route values. Without comparing this extra value, it will always match. <?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0"
xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0 MvcSiteMapSchema.xsd">
<mvcSiteMapNode title="Home" controller="Home" action="Index" metaRobotsValues="index follow noodp noydir">
<!-- Note that you need to configure the "something" parameter for it to be considered in the match here.
Making it an empty string ensures it only matches when the parameter is not provided in the query string. -->
<mvcSiteMapNode title="About" controller="Home" action="About" key="About" something=""/>
<mvcSiteMapNode title="Another About" controller="Home" action="About" something="1234" canonicalKey="About"/>
<mvcSiteMapNode title="Contact" controller="Home" action="Contact" metaRobotsValues="noindex nofollow"/>
<mvcSiteMapNode title="Site Map" controller="Home" action="SiteMap"/>
</mvcSiteMapNode>
</mvcSiteMap> |
One quirk with this, and I'm not sure if it's expected. With the current URL = /Home/About If I define the sitemap with:
then it works as expected, and matches the first node. But if I reverse the node entries:
Then the above URL STILL matches the first one, even though the URL does NOT contain "something=1234". I would expect it to skip that and go to the 2nd one which is a "better" match. |
This sounds like a bug. Opening again until I get a chance to look at it. |
I believe this issue caused a new bug, adding any custom attribute makes the Html.MvcSiteMap().SiteMap.CurrentNode empty, removing it again sets the CurrentNode again. |
To add a custom attribute without messing up your routes you must always add the value to AttributesToIgnore in web.config. This is the way it was in all v4 versions. If I misunderstood and you are in fact trying to add a custom route value (not a custom attribute), this behavior is what changed. Instead of allowing "partial matches" to match and sometimes override complete matches, it makes sense to not allow any match to succeed that doesn't take into account all configured values. The expected behavior is that any route key and value that is configured must match either a route value or a query string value in the incoming request, otherwise you will get a miss and not a hit. If you want a match to always occur on any value for a particular route key (or querystring value), then you need to configure the key in preservedRouteParameters. The URL resolver automatically adds all configured route information to the URLs that MvcSiteMapProvider generates - in other words, those URLs should always match the node they are configured for. However, if you are creating URLs from Action, ActionLink, RouteLink, or some other source, you need to be sure to always provide the route information in the request so it will match (or alternatively use preservedRouteParameters to effectively ignore those keys when considering the match). That said, I would be happy to have a look if you are seeing behavior that is not consistent with this, or not expected. Provide a demo, please. |
Adding the custom attribute to the AttributesToIgnore solved the issue. But I didn't need to do this in 4.6.11 or earlier versions, hence my remark. If this intended, this issue can stay closed. |
See the scenario described here: https://stackoverflow.com/questions/23732793/multiple-path-to-same-razor-view-asp-net-mvc-breadcrum-using-sitemap-provider/23733872#23733872
For which a solution is demonstrated by NightOwl888's demo code from here:
http://www.shiningtreasures.com/post/2013/08/10/mvcsitemapprovider-4-seo-features#canonical-tag (demo code download https://github.com/NightOwl888/MvcSiteMapProvider-SEO-Features-Tutorial/archive/master.zip)
I am having the same problem as asker, in that, with v4.6.6 of MvcSiteMapProvider, the technique described in the referenced post/article does not work, MvcSiteMapProvider can't use the additional route parameter to differentiate the site map node.
e.g. it can't differentiate:
<mvcSiteMapNode title="About" controller="Home" action="About" />
<mvcSiteMapNode title="Another About" controller="Home" action="About" something="1234" />
and always matches the first one regardless of the urls:
http://somesite.com/home/about
http://somesite.com/home/about?something=1234
However, in the referenced sample code, the technique DOES work, but that code is based on v4.0.6. I was able to confirm the different behaviors between versions.
I suspect that the functionality has been broken and this is a bug.
The text was updated successfully, but these errors were encountered: