We have moved to GitHub Issues
Created by Peter Gregory 03 Jun 2013, 11:09:54 Updated by Shannon Deminick 08 Jul 2013, 08:22:29
Is duplicated by: U4-2311
Relates to: U4-2475
I have some simple code that moves documents from one parent to another.
var cs = new ContentService(); var page = cs.GetById(Int32.Parse(HttpContext.Current.Request["id"])); cs.Move(page, ConfigHelper.GetArchiveRootAsNode().Id);
This works...... to a point.
The node is indeed moved, and you can see it has changed its location in the back office tree to the new location, but there are some problems with the cache. The node you move updates it data in the cache, but it is still a child of its old parent, and the URL that is reported on the properties tab is still the old URL even tho the node has moved from a DB perspective but the cache is now not correct.
I have managed to trace the issue to the AppendDocumentXml method in the umbraco.content class on line 380.
Basically this method updates all the attributes of a node that is in cache in place however it does not detect if the node has been moved to a new location (changed parent). So nodes that are moved via the API will never actually be moved unless you brute force refresh the cache which will invalidate the entire cachefile and rebuild from the DB.
To fix I would suggest that the the cache should first do a query on the XML for where the node currently exists, find out what its parent is, and if that parent differs from the new parent id, remove the item from cache file, and then insert the new updated version at the new location.
Work around for the moment is to run library.RefreshContent()
To work around this I followed the pattern that the move dialog was using. If I dont do the following all of the URL info etc is not updated correctly.
library.UpdateDocumentCache(p.Id); library.RefreshContent(); cs.Publish(p);
The second publish is required to actually get it to update its URL on the published node. Without this it remains as the old URL from the old location.
Until 6.1 all business logic commands require people to call methods to update the cache manually. In 6.1 this is taken care of for you. Just like in the legacy business logic APIs you would need to update the cache manually.
I will verify that this does work automatically in 6.1 though.
Also just a note you shouldn't new-up a content service you should use the one assigned to the ApplicationContext.Services
Ok cool, i can replicate this issue... I suppose this issue has existed for a very long time and it's just been worked around by doing things like peter suggested (and has found in the core). Obviously the work around is substantially less performant than just fixing this issue :) Once the issue is fixed, I'll remove all calls to this work around in the core but I guess until people figure it out in their own codebases they'll still be doing the work around for no reason.
This is all fixed up in revision: 86ce48ddc860ac8c01e9d87be5dafef70200c77b
I've also updated the move/copy dialog to use the new API for media and content which now saves on a bunch of queries it was making before. Using the new API there's no need to do the workaround that pete suggested. Also, if you are just using library.UpdateDocumentCache(p.Id); and using the old API you don't need to do the other two lines either. This way we just update the xml structure without rebuilding the whole thing.... much better.
Assignee: Shannon Deminick
Backwards Compatible: True
Affected versions: 6.1.0, 6.0.2, 6.0.3, 6.0.4, 6.0.6, 6.0.5
Due in version: 6.0.7