Saturday, January 31, 2009

IgnoreIfAlreadyExists

Recognize this attribute of the Elements/Module/File element? If you’ve tried to write a feature that provisions a file to a document library, maybe you’ve stumbled across this one. Here’s the official Microsoft documentation is on this attribute:

IgnoreIfAlreadyExists

Optional Boolean. TRUE to provision the view even if the file aready exists at the specified URL; otherwise, FALSE.

Ok, everybody got that? And yes, it really says “aready”.

Now, I don’t know about you, but I read that, and I’m thinking that I can use my feature to overwrite an existing file by simply setting IgnoreIfAlreadyExists to True. Ahhh, if it were that easy, I wouldn’t be writing about it.

What this attribute really does is represented by the following pseudocode:

if (FileExist(fileToProvision)){ 
 if (IgnoreIfAlreadyExists == TRUE) { 
   ; // do nothing 
 } 
 else { 
   throw new Exception(“File Exists!”); 
 } 
} 
else { 
  ProvisionTheFile(fileToProvision); 
}

That’s right. Disregard the documentation, the true way that IgnoreIfAlreadyExists work is it ignores the issue if the file already exists. Useful, right? You’re already thinking how you can put this to use in all your features, right? Sure you are.

So now the question becomes, what kind of voodoo magic is available in SharePoint that allows you to overwrite a previously existing file? If you find it, let me know, because the Google doesn’t have the answer, and neither do I. The best I can offer is to set up a feature receiver and implement FeatureDeactivating to delete your custom file on deactivation:

// delete file in a document library so it can 
// be updated with a new version of the feature
using (SPWeb web = properties.Feature.Parent as SPWeb){ 
  SPList myDocLib = web.Lists["DocLibName"]; 
  if (myDocLib != null) 
  { 
    SPListItemCollection items = myDocLib.Items; 

    for (int i = items.Count - 1; i >= 0; i—) 
    { 
      SPListItem item = items[i]; 
      if (item.Name == "filetodelete") 
      { 
        items[i].Delete(); 
      } 
    } 
  } 
} 

Hardly ideal. Another work around is to manually delete the file before activating the updated feature. Hardly voodoo or magic, eh?

One last tip – if you’re stuck with a feature that deploys a file and you want to update the file and implement a feature receiver to delete the previous version, you can do so by performing your deployment steps in the following order:

Retract Solution
Delete Solution
Add Solution
Deploy Solution
Deactivate Feature
Activate Feature

Your new feature receiver will kick in on the deactivate feature and delete the file for you. Just like magic…

MORE INFORMATION:

How to: Provision a File
SPFeatureReceiver Class

3 comments:

  1. I just ran into issue as well. However you will get an error saying "This item cannot be deleted because it is still referenced by other pages" if there are existing pages that already reference the publishing page when you deactivate the Feature. This is actually important because you may be pushing out a new version of the file and you want to do it through the Feature. I have not been able to figure out a good solution yet. So if I have to update the aspx, looks like the only option would be to try to update the existing file with a new version. Maybe I can try to do this on a FeatureActivation event so that if the file already exists, just try to push it in anyways...

    ReplyDelete
  2. Well - I did some more digging and this is where I will leave it. I saw here (http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/9cd4577d-22f3-4d34-8cf0-a69ce154fa78/) that I could add a Version property however after activation, the publishing page version number did not change. Bummer. As well, changes to the Title property for instance did not take. HOWEVER the changes to the aspx were pushed out! That is all I care about because if the template changes, I want to be able to push that out using the same feature.

    I will get something up on my blog soon about this...

    ReplyDelete
  3. The complete solution can be seen here:

    http://vivek-soni.blogspot.com/2009/07/overwriting-files-using-module-element.html

    ReplyDelete