SPFile.Checkout() and modifying meta data properties

It seems like it should be pretty straightforward. (But then again, nothing ever is when it comes to SharePoint development.) You check a file out, modify its metadata properties and check it back in. I spent something on the order of three hours trying to figure out why that kept blowing up on me when I found a subtle stupid thing that, of course, isn’t explicitly documented.

I thought this code should have worked…

C#


    var list = Web.Lists[listName];
    var item = list.GetItemByUniqueId(new Guid(uniqueId));

    Web.AllowUnsafeUpdates = true;
    var folder = item.File.ParentFolder;

    var checkoutRequired = list.ForceCheckout;

    if (checkoutRequired) {
        item.File.CheckOut();
    }

    var file = folder.Files.Add(listItem.File.Name, 
        listItem.File.OpenBinaryStream(), true,
        "Published by the system after approvals, Pending check-in.", true);

    if (checkoutRequired) {
         file.CheckIn("Automated Go Live Check-in by the Workflow Process");
         file.CheckOut();
    }

   // todo: set all the metadata here
   var linkUrlValue = new SPFieldUrlValue();
   linkUrlValue.Description = "Log Link";
   linkUrlValue.Url = WorkflowInformation.EventLogLink;
   item["LogLink"] = linkUrlValue;

   // explode! "document modified by 'domain\username' at {Now}"
   item.UpdateOverwriteVersion(); 
                    
   if(checkoutRequired)
       file.CheckIn("Automated Go Live Check-in by the Workflow Process", 
            SPCheckinType.OverwriteCheckIn);
                    
   Web.AllowUnsafeUpdates = false;
                    

…But it didn’t. It kept blowing up. I tried various different things, and I couldn’t figure out what was going on. Then I noticed something subtle that all of the examples out there did: They used the file.Item property of the checked out document instead of the original item. I still don’t know why this makes a difference, but if you use it, it works. If you use the ‘original’ item reference instead of the file.Item, it yaks. Below is the only slightly different, yet infinitely more ‘working’ code.

C#


     var list = Web.Lists[listName];
    var item = list.GetItemByUniqueId(new Guid(uniqueId));

    Web.AllowUnsafeUpdates = true;
    var folder = item.File.ParentFolder;

    var checkoutRequired = list.ForceCheckout;

    if (checkoutRequired) {
        item.File.CheckOut();
    }

    var file = folder.Files.Add(listItem.File.Name, 
        listItem.File.OpenBinaryStream(), true,
        "Published by the system after approvals, Pending check-in.", true);

    if (checkoutRequired) {
         file.CheckIn("Automated Go Live Check-in by the Workflow Process");
         file.CheckOut();
    }

   // the CRAZY thing here is you can't use another 
   // reference to the item if the place requires a checkout, even if 
   // it's the one from whence you originally got the file reference 
   // in the first place.
   // You MUST use the file.Item reference to the item or it breaks when 
   // you set the metadata.

   // Your humble author and narrator spent 3 hours trying to figure this out.
                    

   // todo: set all the metadata here
   var linkUrlValue = new SPFieldUrlValue();
   linkUrlValue.Description = "Log Link";
   linkUrlValue.Url = WorkflowInformation.EventLogLink;
   file.Item["LogLink"] = linkUrlValue;
   file.Item.UpdateOverwriteVersion();
                    
   if(checkoutRequired)
       file.CheckIn("Automated Go Live Check-in by the Workflow Process",   
            SPCheckinType.OverwriteCheckIn);
                    
   Web.AllowUnsafeUpdates = false;
                    

You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.

One comment on “SPFile.Checkout() and modifying meta data properties

  1. An Update to this: I found another guy who discovered this incongruity, http://blog.sharepointpress.com/?p=9

    I did some reflector digging. Apparently it loads all fields from the list, not just the ones in the query’s view (which probably exclused the file fields)

    Also, the File.Item method force populates all items with a ModerationType=Moderator attribute. This may be the bit that makes the difference. I’d have to dig some more to confirm it.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

40,479 Spam Comments Blocked so far by Spam Free Wordpress

HTML tags are not allowed.