views:

1240

answers:

2

I am trying to copy an SPListItem (with file) from one site collection to another. I do this by creating the file like this:

var archiveFile = newsArchive.Lists[listName].RootFolder.Files.Add(originalItem.File.Name, originalItem.File.OpenBinary());
var archiveItem = archiveFile.Item;

through a utility method I wrote i then set all field values of the new item to correspond with the original item like so

Utilities.PopulateListItemMetadata(....)

The thing is, this does not persist the Author field.

I tried setting the Author field explicitely in every way imaginable, for instance like so:

string userName = originalItem.GetUser("Created by").LoginName;
SPUser user = newsArchive.SiteUsers[userName];
archiveItem["Author"] = user.ID + ";#" + user.LoginName;
archiveItem.Update();

And like so

string userName = originalItem.GetUser("Created by").LoginName;
SPUser user = newsArchive.SiteUsers[userName];
archiveItem["Author"] = user;
archiveItem.Update();

But as soon as the SPListItem.Update() method is called, the archiveItem["Author"] field has reverted to sharepoint\system. I'm a bit at a loss here, this should work..

P.S. the SPListItem.GetUser method is an extension method

P.P.S. Code is being run from a timer job...

Edit: Did some more digging by adding a new field to the content type and then setting that field to reflect the Author of the original item, but that is not set either. However, the web.EnsureUser(username) does return the correct user. Is this weird or what!?!

A: 

I've experienced the same problem. Have a look at this question.

The way that worked for me is to wrap the same code you have in your final example in elevated privileges.

Edit

Why don't you try replacing:

SPUser user = newsArchive.SiteUsers[userName];

with:

SPUser user = newsArchive.EnsureUser(userName);

Then you will know the user is in the web and also get a reference to them. The SiteUsers collection gives you the users in the site collection - they have not necessarily been added to the web. If SharePoint doesn't find the user it will probably use system account.

Alex Angas
Already checked that out, tried SystemUpdate and Update, it still reverts back to sytemaccount...
Colin
See edit, otherwise I'm not sure!
Alex Angas
I'll give it a try, altough i did try it before. Wrapping everything in RunWithElevatedPrivileges and Add AllowUnsafeUpdates to code. P.S. It is being run from a timer job...
Colin
Didn't work, have no idea what's going on here....
Colin
See edit. Some really weird stuff happening...
Colin
+3  A: 

Found the answer, using

SPFieldUserValue val = new SPFieldUserValue(newsArchive, user.ID, user.Name);
archiveItem["Author"] = val; 
archiveItem.SystemUpdate(false);

did the trick!

Colin
So creating the new SPFieldUserValue is perhaps mapping it correctly to newsArchive? Useful, thanks!
Alex Angas
It seems so, perhaps the constructor needs an explicit reference to the SPWeb?
Colin