MvcSiteMapProvider icon indicating copy to clipboard operation
MvcSiteMapProvider copied to clipboard

Caching per-user

Open ApmeM opened this issue 12 years ago • 15 comments

Hi. Actually it is not an issue - it is a question and feature request :)

The question is: Is it possible to set cache behavior as session (not cache), or maybe remove it at all using config file? If it is not - How can I do this in code?

The reason is why I am asking is that I need to show different menus for different users. And the reason why I can not use Acl - I use customer remote web services, that show me only items user have access to.

So I need to remove cache (which is bad, but acceptable if there is no other way), or use session as a cache. Is it possible?

The feature request: If currently it is impossible - can you add this feature?

ApmeM avatar Jan 14 '12 19:01 ApmeM

+1. This is especially required when using custom node provider for displaying eg. unread messages for current user

rosieks avatar Mar 05 '12 11:03 rosieks

If I understand correctly, return null in DynamicNodeProvider.GetCacheDescription()

ghost avatar Mar 30 '12 17:03 ghost

No, it does not help.. There is a simple check in code:

        CacheDescription cacheDescription = mvcNode.DynamicNodeProvider.&GetCacheDescription();
        if (cacheDescription != null)
        {
            HttpContext.Current.Cache.Add(
                ...
                new CacheItemRemovedCallback(OnSiteMapChanged));

        }

and

    private void OnSiteMapChanged(string key, object item, CacheItemRemovedReason reason)
    {
        ...
                // Clear the sitemap
                Clear();
        ...
    }

this means that root will be cleared only when cache exists. And of course it will not help if 2 users create requests simultaneously.

ApmeM avatar Mar 30 '12 18:03 ApmeM

Actually the main problem of this MvcSitemapProvider is that its base class is "StaticSiteMapProvider". I think to solve this problem it should be based on "SiteMapProvider" (parent of "StaticSiteMapProvider"). In this case it will be possible to clear (or store) cache anywhere we need.

ApmeM avatar Mar 31 '12 10:03 ApmeM

+1 this issue. My breadcrumbs require parameters that are unique for each user. If you dynamically set a node's property (e.g. Title) that property will be cached and displayed for every user. Either there is some configuration that I am unaware of or this is just bogus and needs to be fixed. How is this not a larger issue for people?

seanconnollydev avatar Apr 04 '13 20:04 seanconnollydev

Please take a look at v4: https://github.com/maartenba/MvcSiteMapProvider/tree/v4

Caching is no longer done internally as we are no longer using the Microsoft implementation of SiteMapProvider. There is a new interface ISiteMapCache that can be used to control caching. We are still working on the Nuget packaging, but it is now pretty much feature complete.

It is now set up to handle multiple tenants, custom sitemap builders, dependency injection, etc. and has many new interface based extension points.

Let us know if there are any other features you would like to see.

NightOwl888 avatar Apr 04 '13 21:04 NightOwl888

When is the nuget package for v4 going to be available? This is a major pain point for the application I'm working on.

Kizmar avatar Jun 05 '13 18:06 Kizmar

@Kizmar

I just completed the prerelease Nuget packages today and they can be acquired at this feed: https://www.myget.org/F/mvcsitemapprovider/. Simply put that URL in the settings of your Nuget package manager and set to view prerelease packages in order to view the feed.

Do be aware that anything on that feed that doesn't match the highest build number is a dead package that won't be in the final release. We had to change the naming conventions a few times because Nuget doesn't support multiple versions of MVC. The main packages are named MvcSiteMapProvider.MVCx, where X is the version of MVC (2, 3, or 4).

We also have DI configurations (full or modules only) for 3 different containers (Autofac, Unity, and StructureMap) that are meant to be a starting point - similar to how you get a default template for an MVC project. Note that StructureMap is the most mature out of the 3.

NightOwl888 avatar Jun 12 '13 19:06 NightOwl888

@Kizmar

FYI - v4 is now available (still prerelease) in the Nuget public feed. We could use some feedback whether there are still issues to be resolved so we can make it an official release.

NightOwl888 avatar Jun 23 '13 08:06 NightOwl888

What is the expected date to release V4? We are also looking for solution of caching issue

sushilb avatar Aug 06 '13 09:08 sushilb

@sushilb V4 has been released

maartenba avatar Aug 06 '13 10:08 maartenba

Help me out people. I am having trouble understanding exactly what is being requested here. The first 2 posts had a couple of examples:

  • I need to show different menus for different users. And the reason why I can not use Acl - I use customer remote web services, that show me only items user have access to.
  • Displaying eg. unread messages for current user.

First of all, there is a reason why it is called a _Site_Map - it is because all of the node information pertains to the entire site. Therefore, the main features of MvcSiteMapProvider apply primarily to the entire site:

SiteMaps XML - Used for SEO purposes - Useless for user data unless you are building a social networking site. Html.MvcSiteMap().SiteMap() - Used primarily for SEO, not very useful in user session. Html.MvcSiteMap().Menu() - Valid for user session. Html.MvcSiteMap().SiteMapPath() - Valid for user session. Html.MvcSiteMap().SiteMapTitle() - Used primarily for SEO, not very useful in user session. Html.MvcSiteMap().CanonicalTag() - Used for SEO, not useful in user session. Html.MvcSiteMap().MetaRobotsTag() - Used for SEO, not useful in user session.

So, are you only trying to add items at the user session level to the menu and the sitemap path? That is really the only value I see here, and if that is the case it doesn't make sense to alter the way caching is done so much as to add the ability to dynamically add nodes on a per-request and/or per-session basis.

I am not ruling out that something needs to be added to MvcSiteMapProvider, but please give specific examples of what you are trying to achieve (i.e. which features of the provider you are trying to add user information) so I can better understand your requirements.

Also, give me some hard figures - is 100% of your sitemap data user session data, or only 20%?

NightOwl888 avatar Aug 07 '13 04:08 NightOwl888

On a side note: can a dynamic node provider be used to generate a series of dynamic nodes, containing a user id as an attribute? Next, the visibilityprovider can be used to show only nodes with matching user id.

maartenba avatar Aug 07 '13 12:08 maartenba

On a side note: can a dynamic node provider be used to generate a series of dynamic nodes, containing a user id as an attribute? Next, the visibilityprovider can be used to show only nodes with matching user id.

Not exactly. A dynamic node provider is only run when the cache is built, so you would only get the user id of the user that actually ended up creating the cache, regardless of who is currently accessing it.

Actually, what you describe sounds like what the ACL module is already designed to do - that is to show or hide nodes. I have a feeling the people who want this need more than that - they need to be able to dynamically attach nodes to the sitemap per user and have them cached for that user. What I am trying to find out is how much control is actually needed and how much of the tree is shared between users.

NightOwl888 avatar Aug 07 '13 12:08 NightOwl888

Can we cache a menu based on a role from asp.net identity or a particular area in mvc.

mfsbo avatar Jul 19 '19 11:07 mfsbo