Mittwoch, 10. September 2014

Adding ECB directly to document libraries

Recently I used to look for a possibility to change the SharePoint 2013 ECB (Edit Control Block) from CallOut-Popup back to direct call as known from SharePoint 2010.

I found this way as a quick work around:

But by this solution, the drag-and-drop area is not rendered anymore and the old-fashioned "Add new item"-link below the list returns.

So I spent a little more time with googeling and found this page which adds an additional icon to click which displays the ECB directly:

The site describes the How-To and provides a sandboxed-solution for directly adding to the solutions-gallery of the SiteCollection. After activating everything to do is finished.

As you can see, the standard behaviour is not touched but extended by a new functionality:

It depends to the customer's wish if the three-dots-button now should be hidden (needs some additional work) or both buttons should remain.

Dienstag, 8. Juli 2014

SPFile.Publish() writes 'System Account' to 'ModifiedBy'-column instead of current user

I had the following scenario:

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... 
  ... 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? :-)   

Montag, 30. Juni 2014

Avoiding conflicts if Custom_AddDocLibMenuItems-function is implemented multiple

Today I found a really helpful tip how to add custom items to the SharePoint Edit Control Block (ECB) without getting in conflict with other used Custom_AddDocLibMenuItems-function-calls (for e.g. from another deployed wsp-solution or script added in a Content Editor WebPart (in SharePoint 2010) or ScriptEditor-WebPart (in SharePoint 2013).
You can find it here in Stuart Roberts' blog: