Launching an application from a link in SharePoint

When you are viewing lists of items in SharePoint, the context menu is fantastic as it allows you to edit documents directly from certain native applications. For example with a Word document you are able to select ‘Edit In Microsoft Word’ from the context menu, which when clicked fires up Microsoft Word and enables you to edit the document. However when you start creating your own custom webparts from SharePoint list items, you lose this ability. Today I had the challenge of providing a link to a document that was stored in a SharePoint list, but I needed to be able to fire the document up directly from the link.
 
After quite a bit of trawling through the web I found this great article which really got me going in the right direction:

http://wiki.threewill.com/display/is/2007/10/.

Basically you need to call a javascript method called dispex() which will open the application for you (instead of opening the document as read only).

So within my code I already had my Hyperlink control (lnkDocumentDownload) which was populated by an SPListItem. This also has the URL of the document set in lnkDocumentDownload.NavigateUrl. This needs to be set for this to work, and of course for applications that don’t have integration with SharePoint, they will just use this link to go to the document.

What I needed to additionally add to enable the launching of the application was:

lnkDocumentDownload.Attributes.Add(“onfocus”, “OnLink(this)”);
lnkDocumentDownload.Attributes.Add(
“onclick”, @”DispEx(this,event,’TRUE’,’FALSE’,’FALSE’,’SharePoint.OpenDocuments.3′,’0′,’SharePoint.OpenDocuments’,”,”,”,’2′,’0′,’0′,’0x7fffffffffffffff’)”);

Once I added this in, whenever I clicked the link in my control, it would behave in the same way as clicking on ‘Edit in Microsoft Word’.

I also found some ‘kind of’ (not really) helpful documentation on the javascript methods on the Microsoft website here: http://msdn.microsoft.com/en-us/library/cc264013.aspx

Saving files in ItemUpdated for a SharePoint List

I had an issue today trying to call File.SaveBinary() method of an SPListItem in the ItemUpdated method. Everytime I treid to call it it seemed to throw an error. In the end there was an easy fix for this – make sure AllowUnsafeUpdates is set to true. Once this is set, the binary can be saved no problem. The other method you should call before you save the binary is the this.DisableEventFiring(); method to ensure that the event does not go into an endless loop.
 
ie 
this.DisableEventFiring();
SPListItem item = properties.ListItem;
item.Web.AllowUnsafeUpdates = true;
item.File.SaveBinary(updatedFile);
item.Web.AllowUnsafeUpdates = false;
this.EnableEventFiring();

Invalid Security Validation in SharePoint code

Twice in the past week I have had the issue in my MOSS code where it is throwing an exception: “The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again”

As it turns out the problem isn’t so had to fix. Basically you need to set FormDigestSettings to disabled. This can be done in your code as follows:

SPWebApplication webApp = site.WebApplication;
bool formDigestSettingsEnabled = webApp.FormDigestSettings.Enabled;
webApp.FormDigestSettings.Enabled =
false;
//Do all your code in here where it is throwing the error..
webApp.FormDigestSettings.Enabled = formDigestSettingsEnabled;

This can also be fixed by turning off the security validation for an application in Central Admin (however I probably wouldn’t recommend this):

Central Admin -> Application Management -> General Settings -> Turn security validation off

Impersonation in MOSS 2007

I recently had an issue where I attached a SharePoint event handler to a list item, and when the list item was approved it fired off a group email. Problem was that if the user who approved the item did not have super powered privileges on the system, the event handler would fail due to a permissions error. 

To run the SPSecurity.RunWithElevatedPrivileges method 

This also meant that I could create a method in this class which is called in the SPSecurity.CodeToRunElevated constructor. Also it is worth noting that if you are still getting security validation errors, you need to wrap update() methods with the AllowSafeUpdates method (also shown in code below).

sealed class ScheduleMail
{
   private Guid _siteGuid;
   private string _webUrl;   

   public ScheduleMail(Guid siteGuid, string

webUrl)
   {
      _siteGuid = siteGuid;
      _webUrl = webUrl;
   }   

 

public void SendScheduledMail()
   {
      SPSite mySite = new SPSite(_siteGuid);
      SPWeb myWeb = mySite.OpenWeb(_webUrl);

      // Do the rest of the code requiring privileges      … //Created dispatcher job in here

      //Get around security 

 

 

      myWeb.AllowUnsafeUpdates = true;
      dispatcherJob.Update();
      myWeb.AllowUnsafeUpdates =
false;
   }
}

In the end the final code I implemented was along these lines

override void ItemUpdated(SPItemEventProperties properties)
{
   base.ItemUpdating(properties);
   ScheduleMail mailToSend = new ScheduleMail(properties.SiteId, properties.RelativeWebUrl);
   SPSecurity.CodeToRunElevated codeRequiringElevated = new SPSecurity.CodeToRunElevated(mailToSend.SendScheduledMail);
   SPSecurity.RunWithElevatedPrivileges(codeRequiringElevated);
}