maartenba / MvcSiteMapProvider

An ASP.NET MVC SiteMapProvider implementation for the ASP.NET MVC framework.
Microsoft Public License
537 stars 220 forks source link

NullReferenceException #416

Open Tabgyn opened 8 years ago

Tabgyn commented 8 years ago

After the last update my solution now has the following error with the MVCSiteMapProvider.

View:

  @{
      ViewBag.Title = Html.MvcSiteMap().SiteMap.CurrentNode.Title;
      ViewBag.Description = Html.MvcSiteMap().SiteMap.CurrentNode.Description;
  }

Stack Trace:

[NullReferenceException: Referência de objeto não definida para uma instância de um objeto.]
   MvcSiteMapProvider.Web.Routing.RouteDataExtensions.GetMvcCodeRoutingRouteContext(Type controllerType, String controllerName) +10
   MvcSiteMapProvider.Web.Routing.RouteDataExtensions.SetMvcCodeRoutingContext(RouteData routeData, ISiteMapNode node) +143
   MvcSiteMapProvider.Web.UrlResolver.SiteMapNodeUrlResolver.CreateRequestContext(ISiteMapNode node, TextWriter writer) +63
   MvcSiteMapProvider.Web.UrlResolver.SiteMapNodeUrlResolver.ResolveRouteUrl(ISiteMapNode node, String area, String controller, String action, IDictionary`2 routeValues) +122
   MvcSiteMapProvider.SiteMapNode.GetResolvedUrl() +166
   MvcSiteMapProvider.SiteMapNode.ResolveUrl() +235
   MvcSiteMapProvider.Builder.SiteMapBuilder.VisitNodes(ISiteMapNode node) +44
   MvcSiteMapProvider.Builder.SiteMapBuilder.BuildSiteMap(ISiteMap siteMap, ISiteMapNode rootNode) +256
   MvcSiteMapProvider.SiteMap.BuildSiteMap() +64
   MvcSiteMapProvider.LockableSiteMap.BuildSiteMap() +19
   MvcSiteMapProvider.Loader.SiteMapCreator.CreateSiteMap(String siteMapCacheKey) +110
   MvcSiteMapProvider.Caching.LazyLock.Get(Func`1 activator) +124
   MvcSiteMapProvider.Caching.MicroCache`1.GetOrAdd(String key, Func`1 loadFunction, Func`1 getCacheDetailsFunction) +486
   MvcSiteMapProvider.Web.Html.HtmlHelperExtensions.MvcSiteMap(HtmlHelper helper) +59
   ASP._Page_Views_VisaoGeral_Index_cshtml.Execute() in d:\Projetos\AppConsig\AppConsig.Web.Gestor\Views\VisaoGeral\Index.cshtml:3
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +252
   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +147
   System.Web.WebPages.StartPage.ExecutePageHierarchy() +88
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +106
   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +374
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +89
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +833
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +81
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +186
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137

Someone would have any suggestions of what to do to find out the problem? I've tried to debug but could not view the information in Html.MvcSiteMap ().

Tabgyn commented 8 years ago

I downgrade to 4.6.18 and works fine.

NightOwl888 commented 8 years ago

Thanks for the report.

I know this is happening because controllerType is null in this line, however I have been unable to produce a test case that does this.

Best guess is that you have an invalid Area configuration in your application. I have only found one way to configure Areas that works with MvcSiteMapProvider, which is using conventions all the way.

Once you have worked out what is wrong with your configuration, I would appreciate you building a sample project showing how you get this failure and either post it on GitHub or make it available for download.

I will add a check for a null controller type in this case anyway because this is for interoperability with MvcCodeRouting which doesn't even support Areas, but there should probably be an exception put in for invalid Area configurations so they will work with security trimming, rather than just failing silently like they are now.

Tabgyn commented 8 years ago

I believe that in my case the problem was null PARENT_ID. I updated the values for 0 and updated to version 4.6.20 and is working.

NightOwl888 commented 8 years ago

Thanks, but I am more interested to know what change to your configuration you need to make to get it working with 4.6.19. If your root node is an [MvcSiteMapNodeAttribute], its parent ID should be null, but all other nodes should have one.

Are you using Areas in your application? If so, have you configured your routes to include the namespace of the controllers? Are you using an AreaRegistration class or have you set up custom routing for the Areas?

If you are not using Areas, I suppose the other thing that could cause this is if one of your nodes is missing a Controller property/attribute, but I was unable to find a way to make this happen that would cause this failure.

Tabgyn commented 8 years ago

No I'm not using areas. I downgraded to version 4.6.19 and still does not work, I honestly have no idea of what can be. I did not make any changes in my code except change the null value to 0 in parent_id in the database and build 19 is still not working.

In build 18 and 20 is OK.

My Mvc.sitemap

<?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 key="0" title="root" clickable="false">
    <mvcSiteMapNode title="" dynamicNodeProvider="AppConsig.Web.Gestor.AppDynamicNodeProvider, AppConsig.Web.Gestor"/>
  </mvcSiteMapNode>
</mvcSiteMap>

and my dynamic node provider

public class AppDynamicNodeProvider : IDynamicNodeProvider
    {
        private readonly AppContext _context = new AppContext();

        public IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            var usuarioLogado = ((AppPrincipal)HttpContext.Current.User);
            var permissoes = _context.Usuarios.Include(u => u.Perfil)
                .Include(u => u.Perfil.Permissoes)
                .First(u => u.Id == usuarioLogado.Id).Perfil.Permissoes;

            var nodeList = new List<DynamicNode>();
            foreach (var permissao in permissoes)
            {
                var dNode = new DynamicNode
                {
                    Key = permissao.Id.ToString(),
                    ParentKey = permissao.ParenteId.ToString(),
                    Title = permissao.Nome,
                    Description = permissao.Descricao,
                    Url = permissao.Url,
                    Action = permissao.Acao,
                    Controller = permissao.Controle,
                    Order = permissao.Ordem
                };

                //Quando for CRUD
                if (permissao.EhCRUD)
                {
                    var cList = permissao.Atributos.Split(';');
                    dNode.PreservedRouteParameters = cList;
                }

                dNode.Attributes.Add("icon", permissao.ClasseIcone);
                dNode.Attributes.Add("visibility", permissao.MostrarNoMenu ? string.Empty : "!MenuHelper");

                nodeList.Add(dNode);
            }

            return nodeList;
        }

        public bool AppliesTo(string providerName)
        {
            if (string.IsNullOrEmpty(providerName))
                return false;

            return GetType() == Type.GetType(providerName, false);
        }
    }

in Database

Id Nome Descricao Url Acao Controle ClasseIcone ParenteId Ordem EhPadrao MostrarNoMenu EhCRUD Atributos
1 Visão Geral Dados e informações gerais Index VisaoGeral fa fa-dashboard 0 1 1 1 0
2 Minha conta Conta Usuario 0 2 1 0 0