Documents that are dragged&dropped in a documentlibrary should be enriched with additional metadata and after that they should be published.
The document library has versions enabled with minor versions.
All action takes place in a SPItemEventReceiver, the details for that I'll omit for now.
Now when it came to do spFile.Publish(), after that the "ModifiedBy"-Column has 'System Account' instead of the current user and there seemed no way to set it manually. Neither the Publish-Method had a parameter to set the current user, nor SPListItem.SystemUpdate or SPListItem.UpdateOverwriteVersion worked:
- SystemUpdate won't save changes to CreatedBy/Created or ModifiedBy/Modified-fields.
- UpdateOverwriteVersion would work but creates a minor version (1.1 in my case)
But then I found a solution here.
I couldn't believe that and tried it out and it really worked! The post said, the SPSite-Object should be opened by adding the SPUserToken to the constructor and then SPFile.Publish() will save the user as last modifier. To show a concrete minimal example:
using (SPSite spSite = new SPSite(properties.SiteId, properties.OriginatingUserToken))
{
using (SPWeb spWeb = spSite.OpenWeb(serverRelativeWebUrl))
{
SPListItem spListItem = spWeb.GetListItem(properties.Web.ServerRelativeUrl); // make sure, the file is checked in before or try to acces or you get a file-not-found-error here
SPFile spFile = spListItem.File;
... add more data to spListItem...
spListItem.SystemUpdate(false);
... check for enabled versions, etc...
spFile.Publish(); // writes the SPUser related to the SPUserToken from properties.OriginatingUserToken to 'ModifiedBy'-column, if SPSite is instantiated with new SPSite(properties.SiteId) only, 'System Account' is used
}
}
properties
is the default SPItemEventProperties-object from the SPItemEventReceiver.Pay attention, the "Modified"-Column (DateTime) changes to DateTime.Now. But this was not in the focus of my requirement.
I always thought, using new SPSite(Guid) would open the SPSite in current user's context but that's not true as a closer look by using Reflector shows. Have a look at two of the default constructors from SPSite-class:
public SPSite(System.Guid id) : this(id, SPFarm.Local, SPUrlZone.Default, SPSecurity.GetDefaultUserToken())
public SPSite(System.Guid id, SPUserToken userToken) : this(id, SPUrlZone.Default, userToken)
Do you note the difference? :-)