maartenba / MvcSiteMapProvider

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

Error with 'PreservedRouteParameters' - v4.6.22 #424

Open luboganchev opened 8 years ago

luboganchev commented 8 years ago

Hi NightOwl88,

I am using 4.6.22 version of MVCSiteMapProvider. Linked to #382 I still get this error with both using parameter in RouteValues and PreservedRouteParameters, which is not allowed. I was getting this error also in the previous versions.

My configurations are: In web.config <add key="MvcSiteMapProvider_IncludeAssembliesForScan" value="XXX.XX" /> <add key="MvcSiteMapProvider_UseExternalDIContainer" value="false" /> <add key="MvcSiteMapProvider_ScanAssembliesForSiteMapNodes" value="true" /> <add key="MvcSiteMapProvider_EnableLocalization" value="true" /> <add key="MvcSiteMapProvider_CacheDuration" value="5" /> In 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">

`

My full error is:

The node with key 'Home_Index_GET$resources:Sitemap, Home__Task_IndexGET$resources:Sitemap, Task__Task_EditGET$resources:Sitemap, TaskDetails_' and title 'Task Details' has 'id' configured in both RouteValues and PreservedRouteParameters, which is not allowed.

PreservedRouteParameters copies the route value from the current HTTP request which would overwrite your configured RouteValue in every case. Either remove 'id' from PreservedRouteParameters or as a configured RouteValue.

Alternatively, if you are configuring the node in XML and intend to use 'id' as a custom attribute, use the 'MvcSiteMapProvider_AttributesToIgnore' configuration setting to ensure 'id' is not automatically added to RouteValues. If using external DI, this setting is injected into the constructor of 'SiteMapXmlReservedAttributeNameProvider'.

This error occurs randomly and there is no specific way to reproduce it all the time. Is there anything that I am doing wrong?

Best regards, Lyubomir Ganchev

NightOwl888 commented 8 years ago

Your issue is actually a duplicate of #310. The issue here is that when the cache expires at the precise moment when a request is being made + more than one HTML helper on the page, the SiteMap is unloaded between HTML helper requests, but the request caching done on the PreservedRouteParameters makes them conflict when the SiteMap is reloaded.

I am actually a little surprised that people haven't complained more about this. I have been holding off to have enough changes to make a minor release (since this will break external DI configurations), but as of late I haven't had much time to contribute.

In the meantime, there is a workaround you can use by wrapping the existing CacheProvider in an external DI configuration.

waynebrantley commented 8 years ago

@NightOwl888 Any chance for a fix and nuget package on this?

14skywalker commented 7 years ago

Note on using the suggested workaround in combination with dependency injection: the class interface and constructor make the DI resolver recurse endlessly.

public class RequestCacheProvider<T> : ICacheProvider<T>
{
    public RequestCacheProvider(IMvcContextFactory mvcContextFactory
        , ICacheProvider<T> subCacheProvider)
    { 

I changed it to

public class RequestCacheProvider<T> : ICacheProvider<T>
{
    public RequestCacheProvider(IMvcContextFactory mvcContextFactory
        , RuntimeCacheProvider<T> subCacheProvider)
    { 

And in the MvcSiteMapProviderContainerExtension use

         this.Container.RegisterType(typeof(ICacheProvider<>), typeof(RequestCacheProvider<>));
ianwitherow commented 7 years ago

Just wanted to chime in since I'm having this issue as well. Every once in awhile some unlucky user will have this error pop up. Any chance of a minor update to address it?

Adam-78 commented 6 years ago

Same here I'm having this issue as well randomly. Any updates on this and workaround where you are not using an external DI container?

ianwitherow commented 6 years ago

@Adam-78 Not sure if this will help you, but I did figure out why it was happening on my site. In my layout page, I would generate the top navigation menu, then everything else for the page, and finally I would render my site's footer menu. The error would happen if someone got unlucky and requested a page, navigation menu would generate, and while the body of the page was loading the menu's cache expired, and it would then attempt to render the site's footer menu and fail.

My fix was to just generate both the navigation and footer menus at the same time into variables, and use those variables where they should be rendered. Haven't seen this error pop up again in about 2 months.

No idea if your setup is similar, but hopefully this helps somebody.

PerRoman commented 6 years ago

I have the same issue. I have found MvcSiteMapProvider (version 4.6.23) in https://www.myget.org/. Please tell us, did you fix this problem in version 4.6.23? Should we use a workaround?