Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Route values not preserved correctly in v4? #207

Closed
olavkraakenes opened this issue Aug 15, 2013 · 8 comments
Closed

Route values not preserved correctly in v4? #207

olavkraakenes opened this issue Aug 15, 2013 · 8 comments

Comments

@olavkraakenes
Copy link

When a child action belongs to a different controller, the route values seems to get lost. This did not seem to be the case in v3. Is there something I'm missing here?

Parent:
<mvcSiteMapNode title="View project" controller="Project" action="ViewProject" preservedRouteParameters="ProjectId">

Child:
<mvcSiteMapNode title="View written assignment" controller="WrittenAssignment" action="ViewWrittenAssignment" preservedRouteParameters="AssignmentId">

When I open the child view, I see that the CurrentNode.ParentNode.PreservedRouteParameters contains "ProjectId", but the route values collection does not.

Please advise.

Olav

@NightOwl888
Copy link
Collaborator

Preserved route parameters definitely had some refactoring in the new version.

Could you build a small project that exhibits the problem and either post it on GitHub or zip it and make it available for download so we can check it out? Sometimes issues are difficult to reproduce if we don't use the same configuration.

@NightOwl888
Copy link
Collaborator

Ok, I think I understand what is happening here.

In v3, there were caching problems - that is, when preserving route parameters, they would be written to the main cache. This inadvertently shared your route parameters between all users of your site. In v4, this has been fixed - it is now writing these values to the request cache only. However, now it is no longer going to save the values across requests.

In a case like yours, where you are using a different action parameter name for each node, v3 would have seemed to remember them because of this flaw. What you probably didn't notice was that if another user came along and overwrote that parameter, it would forget on your end as well.

The bottom line is - the behavior you were using was relying on a bug. Preserving the route parameters across requests was an unintentional side effect. If you want to mimic the same behavior, I would suggest either adding all possible IDs to your sitemap using a couple of DynamicNodeProviders. Alternatively, you could use session state or cache (with the user id incorporated in the cache key) to save your route parameters and write them back to the nodes on each request.

SiteMaps.Current.CurrentNode.RouteValues["projectId"] = userCachedProjectId;

@maartenba - I am curious what your take is on this. Should we add a user cache for preserved route parameters to mimic the behavior in v3?

@olavkraakenes
Copy link
Author

Thank you for clarifying this! I have thought about using a DynamicNodeProvider, but as the number of nodes would increase dramatically, I fear performance would suffer??

Writing directly to the node could possibly solve this issue for me - I can confirm that route values collection now contains the correct key/ value pair. It brings up another issue however: The changes in the route values collection does not seem to be picked up by the sitemap path. Only when I manually enter "ProjectId=1" in the request string, the path is correctly displayed. What am I missing?

If you still want me to put together a sample project, please let me know. (?)

Olav

@NightOwl888
Copy link
Collaborator

As for performance, there are some things to keep in mind.

  1. Adding every possible record to the sitemap ensures they will be output in your /sitemaps.xml endpoint, which is a mechanism that search engines use to index your pages. Making sure all pages are listed is a good thing.
  2. There is typically a single cache that is shared between all users of your site (it can be configured with multiple caches as well).
  3. A node object is small and doesn't take up much memory. You should be able to load 10s to 100s of thousands of nodes on most average servers without issues.
  4. If you do run out of memory, the cache can be extended to write to the file system.

I noticed a bug in the sitemap path that I fixed last night, but I am not sure if it made it into one of the releases. You could try installing from the continuous integration feed at https://www.myget.org/F/mvcsitemapprovider/ (add this URL to your NuGet package manager settings) to see if it helps.

If that doesn't work, seeing a demo project with a similar configuration could prove helpful. Also, building the project may inadvertently reveal problems with your configuration..

@olavkraakenes
Copy link
Author

Thanks again for really useful input! Here's a simple demo project:

http://sdrv.ms/19rgy8e

I've tried setting the ProjectId manually in the AssignmentController, but as you can see - the sitemap path does not reflect the value, although it's present in the route values collection. If I enter "ProjectId=whatever" in the querystring, it is picked up immediately.

Olav

@NightOwl888
Copy link
Collaborator

The only problem I found with your setup is that you were setting the route value to the wrong node:

//SiteMaps.Current.CurrentNode.RouteValues["ProjectId"] = "1";
SiteMaps.Current.CurrentNode.ParentNode.RouteValues["ProjectId"] = "1";

Changing the above line makes it work like you expect.

@olavkraakenes
Copy link
Author

Of course! That makes complete sense. Hm... I really shouldn't do work during the weekends :) Thanks a lot for useful insights on both this issue and the performance side of dynamic nodes...

Olav

@NightOwl888
Copy link
Collaborator

I have created a blog post that covers tracking a user's position in the sitemap - How to Make MvcSiteMapProvider Remember a User’s Position

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants