当前节点出现空值。在这种情况下,我无法弄清楚如何让MvcSiteMapProvider解析节点。
这是匹配所需的节点
<mvcSiteMapNode title="Policy" route="Details" typeName="Biz.ABC.ShampooMax.Policy" preservedRouteParameters="id" />
这是路线:
routes.MapRoute(
"Details",
"Details/{id}",
new { Controller = "Object", Action = "Details" }
).RouteHandler = new ObjectRouteHandler();
点击的链接:
http://localhost:36695/MyGreatWebSite/Details/121534455762071
这是正确的路线。只有MvcSiteMapProvider.SiteMaps.Current.CurrentNode
为空。
答案 0 :(得分:2)
null
的{{1}}结果表示传入请求与CurrentNode
中的任何节点都不匹配。在您的情况下,有4个不同的问题可能导致此问题:
SiteMap
不一定(必然)与您在路线http://localhost:36695/MyGreatWebSite/Details/121534455762071
中指定的网址格式相匹配。如果您的站点作为"Details/{id}"
下的IIS应用程序托管,则可能。IISROOT/MyGreatWebSite/
未指定匹配的mvcSiteMapNode
或controller
。 action
仅作为额外的标准(意味着在匹配中仅考虑命名的路线),但是还需要提供所有参数以便与路线匹配。 / LI>
route
,这可能会改变路线与网址的匹配方式。如果没有看到RouteHandler
中的代码,就无法判断这是否或如何影响路径与网址的匹配。ObjectRouteHandler
配置中有自定义属性typeName
。除非您已指定ignore this attribute,否则网址中也需要匹配,即mvcSiteMapNode
。我建议不要使用自定义http://localhost:36695/MyGreatWebSite/Details/121534455762071?typeName=Biz.ABC.ShampooMax.Policy
来匹配网址。这样做的效果使您的传入路由(URL到MVC)的行为与传出路由(生成链接到其他页面的URL)不同。由于RouteHandler
使用路由的两个部分,如果您只更改传入路由而不更改要匹配的传出路由,则会导致URL生成问题。相反,我建议您使用子类MvcSiteMapProvider
,您可以在其中控制路线的两侧。有关自定义RouteBase
子类的示例,请参阅this answer。
但是,请注意,传统路由非常强大,您可能不需要为此简单方案创建RouteBase
子类。
答案 1 :(得分:0)
我通过将mvc站点地图提供程序项目添加到我自己的解决方案中并逐步完成mvc站点地图提供程序代码来查看我的节点未匹配的原因。必须改变一些事情。我通过执行以下操作来修复它:
<强> Mvc.sitemap 强>
<mvcSiteMapNode title="Policy" controller="Object" action="Details" typeName="Biz.ABC.ShampootMax.Policy" preservedRouteParameters="id" roles="*"/>
<强> RouteConfig.cs 强>
routes.MapRoute(
name: "Details",
url: "details/{id}",
defaults: new { controller = "Object", action = "Details", typeName = "*" }
).RouteHandler = new ObjectRouteHandler();
现在起初它不想像这样工作,但我像这样修改了提供者:
RouteValueDictionary.cs (添加了通配符以匹配值)
protected virtual bool MatchesValue(string key, object value)
{
return this[key].ToString().Equals(value.ToString(), StringComparison.OrdinalIgnoreCase) || value.ToString() == "*";
}
SiteMapNode.cs (已更改requestContext.RouteData.Values
)
/// <summary>
/// Sets the preserved route parameters of the current request to the routeValues collection.
/// </summary>
/// <remarks>
/// This method relies on the fact that the route value collection is request cached. The
/// values written are for the current request only, after which they will be discarded.
/// </remarks>
protected virtual void PreserveRouteParameters()
{
if (this.PreservedRouteParameters.Count > 0)
{
var requestContext = this.mvcContextFactory.CreateRequestContext();
var routeDataValues = requestContext.HttpContext.Request.RequestContext.RouteData.Values;// requestContext.RouteData.Values;
我认为第二次修改并不是绝对必要的,因为我的请求上下文没有被缓存;如果是的话它会起作用。我不知道如何缓存它。
这是第一个使路由值符合使其工作的通配符(*)的修改。这似乎是一个黑客,也许有一个内置的方式。
使用以下命令忽略typeName属性:
<强>的web.config 强>
<add key="MvcSiteMapProvider_AttributesToIgnore" value="typeName" />
使另一个节点中断:
<强> Mvc.sitemap 强>
<mvcSiteMapNode title="Policies" url="~/Home/Products/HarvestMAX/Policy/List" productType="HarvestMax" type="P" typeName="AACOBusinessModel.AACO.HarvestMax.Policy" roles="*">
这就是我不这样做的原因。