Я использую ASP.NET MVC SiteMapProvider 3.0 на моей странице MVC3 (.NET Framework 4.0). Я переключился с SiteMapProvider v2 на 3.0 во время разработки, но у меня также была описанная проблема в v2.
SiteMapProvider указывается в файле Web.config следующим образом:
<siteMap defaultProvider="MvcSiteMapProvider" enabled="true">
<providers>
<clear/>
<add name="MvcSiteMapProvider"
type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider"
siteMapFile="~/Web.Sitemap"
securityTrimmingEnabled="false"
cacheDuration="5"
enableLocalization="false"
scanAssembliesForSiteMapNodes="true"
skipAssemblyScanOn=""
attributesToIgnore="bling,visibility"
nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider"
controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider"
actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider"
aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider"
siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider"
siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider"
siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider"/>
</providers>
</siteMap>
Страница использует основную и административную области, а карта сайта содержит узлы для обеих этих областей, включая некоторые DynamicNodes:
<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="false">
<mvcSiteMapNode title="Startseite" controller="Home" action="Index" changeFrequency="Monthly" updatePriority="Normal">
<!--Main Page-->
<mvcSiteMapNode title="Produktkatalog" controller="Products" action="Index" >
<mvcSiteMapNode title="Fahrräder" controller="Bikes" action="List" key="bikes_" >
<mvcSiteMapNode title="Marken" controller="Bikes" action="List" dynamicNodeProvider="Grauthoff.WebUI.Infrastructure.BikeBrandsDynamicNodeProvider, Grauthoff.WebUI">
<mvcSiteMapNode title="Details" controller="Bikes" action="Details" dynamicNodeProvider="Grauthoff.WebUI.Infrastructure.BikeDetailsDynamicNodeProvider, Grauthoff.WebUI" />
</mvcSiteMapNode>
<mvcSiteMapNode title="Kategorien" controller="Bikes" action="List" dynamicNodeProvider="Grauthoff.WebUI.Infrastructure.BikeCategoriesDynamicNodeProvider, Grauthoff.WebUI" />
</mvcSiteMapNode>
<mvcSiteMapNode title="Absperrpfosten" controller="Barriers" action="List" key="barriers_" >
<mvcSiteMapNode title="Kategorien" controller="Barriers" action="List" dynamicNodeProvider="Grauthoff.WebUI.Infrastructure.BarrierCategoriesDynamicNodeProvider, Grauthoff.WebUI" />
</mvcSiteMapNode>
<mvcSiteMapNode title="Tresore" controller="Safes" action="List" key="safes_" >
<mvcSiteMapNode title="Marken" controller="Safes" action="List" dynamicNodeProvider="Grauthoff.WebUI.Infrastructure.SafeBrandsDynamicNodeProvider, Grauthoff.WebUI">
<mvcSiteMapNode title="Details" controller="Safes" action="Details" dynamicNodeProvider="Grauthoff.WebUI.Infrastructure.SafeDetailsDynamicNodeProvider, Grauthoff.WebUI" />
</mvcSiteMapNode>
<mvcSiteMapNode title="Kategorien" controller="Safes" action="List" dynamicNodeProvider="Grauthoff.WebUI.Infrastructure.SafeCategoriesDynamicNodeProvider, Grauthoff.WebUI" />
</mvcSiteMapNode>
</mvcSiteMapNode>
<mvcSiteMapNode title="Marken" controller="Brands" action="Index" />
[...]
<!--Admin Area-->
<mvcSiteMapNode title="Start" controller="Home" action="Index" area="Admin" />
[...]
</mvcSiteMap>
На главной странице я использую
<%: Html.MvcSiteMap (). Menu (false)%>
для рендеринга навигации страницы, используя следующий DisplayTemplate:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl`1[ [MvcSiteMapProvider.Web.Html.Models.MenuHelperModel,MvcSiteMapProvider] ]" %>
<%--this controls the output of the main navigation bar on the main page--%>
<ul id="MainNav">
<% foreach (var node in Model.Nodes) { %>
<%--skip AdminArea nodes--%>
<% if (node.Area.Equals("Admin")) { %>
<% continue; %>
<% } %>
<%--hightlight active node using a CSS class--%>
<% if (node.IsCurrentNode || node.IsInCurrentPath || (SiteMap.CurrentNode != null && SiteMap.CurrentNode.Url.Equals(node.Url)))
{ %>
<li class="naviActive"><%=Html.DisplayFor(m => node)%>
<% } %>
<% else { %>
<li class="naviInactive"><%=Html.DisplayFor(m => node)%>
<% } %>
</li>
<% } %>
</ul>
В общем, все работает нормально, но у меня есть одна большая проблема, которая пока еще не решена:
Если я открываю один из сайтов, связанных с DynamicNode, в браузере и просто простаиваю несколько минут (или если я перестраиваю решение в VS в фоновом режиме), а затем обновляю страницу в браузере, я всегда получаю исключение System.NullReferenceException с следующая ошибка источника и трассировка стека:
Zeile 29: <div id="navi">
Zeile 30: <%--Navigation--%>
Zeile 31: <%: Html.MvcSiteMap().Menu(false)%>
Zeile 32: </div>
Zeile 33: </div>
[NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.]
MvcSiteMapProvider.DefaultSiteMapProvider.GetSiteMapNodeFromXmlElement(XElement node, SiteMapNode parentNode) in D:\Downloads\smp\Main\src\MvcSiteMapProvider\MvcSiteMapProvider\DefaultSiteMapProvider.cs:1348
MvcSiteMapProvider.DefaultSiteMapProvider.BuildSiteMap() in D:\Downloads\smp\Main\src\MvcSiteMapProvider\MvcSiteMapProvider\DefaultSiteMapProvider.cs:483
[MvcSiteMapException: An error occured while building the sitemap... Check the InnerException for more details.]
MvcSiteMapProvider.DefaultSiteMapProvider.BuildSiteMap() in D:\Downloads\smp\Main\src\MvcSiteMapProvider\MvcSiteMapProvider\DefaultSiteMapProvider.cs:563
MvcSiteMapProvider.DefaultSiteMapProvider.GetRootNodeCore() in D:\Downloads\smp\Main\src\MvcSiteMapProvider\MvcSiteMapProvider\DefaultSiteMapProvider.cs:131
MvcSiteMapProvider.DefaultSiteMapProvider.get_RootNode() in D:\Downloads\smp\Main\src\MvcSiteMapProvider\MvcSiteMapProvider\DefaultSiteMapProvider.cs:103
MvcSiteMapProvider.Web.Html.MenuHelper.Menu(MvcSiteMapHtmlHelper helper, Boolean showStartingNode) in D:\Downloads\smp\Main\src\MvcSiteMapProvider\MvcSiteMapProvider\Web\Html\MenuHelper.cs:45
ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in d:\inetpub\vhosts\grauthoff-shop.de\httpdocs\Views\Shared\Site.Master:31
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Control.Render(HtmlTextWriter writer) +10
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Page.Render(HtmlTextWriter writer) +29
System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +43
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060
Это происходит как в режиме отладки, так и в режиме выпуска и даже на моем удаленном веб-сервере. Очевидно, это мешает мне опубликовать проект. Поскольку у меня нет ни малейшего представления, что может вызвать это, я очень благодарен за любую помощь!
€ dit 01.06.2011: Ранее я использовал сборку релиза RC 3.1.0, но теперь прикрепил ветку SVN 3.1.0 к своему проекту, чтобы иметь возможность отладить исключение. Я обнаружил, что исключение происходит в методе
защищенный MvcSiteMapNode
GetSiteMapNodeFromXmlElement (XElement
узел, SiteMapNode parentNode)
в следующих строках, где defaultValue.Value равно нулю (siteMapNode и defaultValue не равны нулю):
Line 1379: if (siteMapNode[defaultValue.Key] == null)
Line 1380: {
Line 1381: siteMapNode[defaultValue.Key] = defaultValue.Value.ToString();
Line 1382: }
Я также обнаружил, что, как только произошла ошибка, нельзя снова запросить действие основного контроллера - не обновляя страницу в браузере и не открывая новое окно или вкладку браузера. Сначала вы должны запросить действие с URL-адресом нединамического узла на верхнем уровне в иерархии карты сайта, а затем вы можете снова запросить динамический дочерний узел. Это почти похоже на проблему с кешированием или на то, что какой-то объект карты сайта уничтожен GC, а затем не воссоздан должным образом.