SharePoint: SPFile.SaveBinary, Updating Office Document Library Items and Automatic Document Property Promotion


Using the Object Model, adding items to a SharePoint document library is easy enough, given the code below you can add a new document library item and set it’s meta data at the same time.

			var metadata = new Hashtable
			               	{
			               		{"vti_title", "some document title"}
			               	};

			var documentFile = list.RootFolder.Files.Add("mydoc.docx", documentBytes, metadata, true);

But, how to  update a doucment library item? Well given the same document url (LinkFilename) you can just call the above code again, assuming you set the last (bool) parameter to true, to overwrite any existing file.

There is another way to update just the document file of a document library item, and that is to use SPFile.SaveBinary().

			using (var site = new SPSite(<a href="http://portal">http://portal</a>))
			using (var web = site.OpenWeb())
			{
				SPFile file = web.GetFolder("Documents").Files["mydoc.docx"];
				using (var fs = new FileInfo(@"E:\Documents\mydoc.docx").OpenRead())
				{
					documentBytes = ..... // get the documents bytes
				}
				file.SaveBinary(documentBytes);
			}

Using this technique you can update just the document file part of a document library item.

This works out great, except when it doesn’t………….well not always.

When you’re dealing with non-Office documents, with or without content types, it does work out just fine. You get the expected results every time.

When you’re dealing with Office documents, SharePoints automatic document property promotion steps in with it’s size 12 boots and kicks you in the shins!

If you call the above code you’ll find that your document library item has been set to the default content type (if you’re using content types) and all your custom field settings have been wiped (or at least set to their defaults), and this is due to the way SharePoint property promotion works with Office documents in order for it to keep document properties in synch with SharePoint list item properties.

If this is a problem for you (i.e you want to programmatically manage SharePoint properties), one possible workaround is to create an event handler to handle the checkin/checkout events and set the item field values to the old field values during checkin, as described in this post.

Another solution involves setting the SPWeb.ParserEnabled property as shown;

			using (var site = new SPSite("http://portal"))
			using (var web = site.OpenWeb())
			{
				SPFile file = web.GetFolder("Documents").Files["mydoc.docx"];
				using (var fs = new FileInfo(@"E:\Documents\mydoc.docx").OpenRead())
				{
					documentBytes = ..... // get the documents bytes
				}
				web.ParserEnabled = false;
				web.Update();
				file.SaveBinary(documentBytes);
				web.ParserEnabled = true;
				web.Update();
			}

 This has the effect of temporarily disabling automatic document property promotion, obviously you probably don’t want to turn it off permanently since this feature plays an important part of Search – the ability for Office document properties to be surfaced within SharePoint and therefore to be searchable.

Published by

Phil Harding

SharePoint Consultant, Developer, Father, Husband and Climber.

2 thoughts on “SharePoint: SPFile.SaveBinary, Updating Office Document Library Items and Automatic Document Property Promotion

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s