Tuesday, August 21, 2007

SPFileCollection.Add ignores title property on upload

Using SPFileCollection.Add (String, Byte[], Hashtable) as described on MSDN I found that it's simply isn't working properly :-(

Adding system properties doesn't work:

dim oHash as new hashtable
oHash.add("DocumentType","Contract")
oHash.add("Title","Leasing agreement with Smart Leasing Inc.")
oFile = oFolder.Files.Add(,,oHash)

oFile.Item("Title") is not equal to "Leasing agreement...".

The only way is to modify it manually after having added the file, e.g.
dim li as SPListItem
li = oFile.Item
li("Title")="Leasing agreement..."
li.UpdateOverwriteVersion(); ' In order to avoid creating a new version

Any explanations why "Title" property cannot be set in oHash would be appreciated.

Other problems with Add has been reported various places. This blog is worth reading.

14 comments:

Lorin Davis said...

Did you ever find a resolution to this?

I'm having the same problem, it appears that the properites will only update if they are in the same order in your hashtable as they appear in your Sharepoint List, grr frustraiting.

Morten Marquard said...

Do you know if the same applies to the Created and CreatedBy properties.

Anonymous said...

Haven't checked this, but "Title" may technically be a computed field off of some lower level field like "FileLeafRef". Also, when you make the file.Item call it hits the database for the refreshed item. So setting title like this has a performance penalty.

Dave Hunter said...

A bit late but only just stumbled accross this blog. You need to use:

hashTable.Add("vti_title","Document Title");

Dave

Morten Marquard said...

Hi Dave,
Thanks a lot. And it's never too late.
Any chance you came arcross similar suggestions for Created and CreatedBy when adding new documents?

Dave Hunter said...

Hi Morten,

Try vti_created and vti_author. I'm sure SharePoint refers to the Author as the Created By and the Editor as the Modified By with document libraries.

vti is a legacy thing from previous versions (acronym from Vermeer Technologies Incorporated, which MS acquired years ago) so some of the old calls and directories still reflect this.

Hope this helps
Dave

Morten Marquard said...

Hi Dave,
Unfortunately adding "vti_" doesn't solve the problem. I have tested it.

Thanks for clarification of the vti acronym.

Morten

Dave Hunter said...

OK. I've just wrote some quick and dirty code to get the properties of an existing SPFile (word doc). The code looks like:

SPSite site = new SPSite("http://intranet");
foreach (DictionaryEntry prop in site.RootWeb.Lists["Documents"].Items[0].File.Properties)
{
System.Diagnostics.Debug.WriteLine(prop.Key + " : " + prop.Value);
}


This returns the following:

vti_canmaybeedit : true
_Author : Administrator
vti_timecreated : 08/12/2008 12:33:41
_Category :
_Status :
vti_timelastmodified : 08/12/2008 12:33:41
ContentType : Document
vti_title :
vti_replid : rid:{CE94E052-257E-4B95-946B-3B2B91CC0957}
vti_parserversion : 12.0.0.6219
PublishingStartDate :
vti_level : 1
vti_rtag : rt:CE94E052-257E-4B95-946B-3B2B91CC0957@00000000001
vti_sourcecontrolcookie : fp_internal
ContentTypeId : 0x0101003087515E5634704F98FD43AEB256E309
vti_docstoreversion : 1
vti_filesize : 17107
vti_sourcecontrolversion : V1.0
vti_docstoretype : 0
vti_author : DOMAIN\administrator
vti_modifiedby : DOMAIN\administrator
PublishingExpirationDate :

Notice the _Author (friendly name) or vti_author (logon) and vti_timecreated

Hope this helps
Dave

Morten Marquard said...

Hi Dave,
Thanks for your comments. But when you add a document to SharePoint with the hashcollection containing the properties the vti_... properties doesn't work. Wish they did.

Have you tested that part?

Morten

Dave Hunter said...

I've just tested it and the title is set using the following code. By the way, I don't think you will be able to set the created or created by as these are automatically set by SharePoint.

SPSite site = new SPSite("http://intranet");
SPWeb rootWeb = site.RootWeb;

FileStream fStream = File.OpenRead(@"C:\pathtotextfile\TextFile1.txt");
Hashtable props = new Hashtable();
props.Add("vti_title", "hello world");

rootWeb.Files.Add("http://intranet/Documents/textfile2.txt", fStream, props);

Remember to add the dispose calls or use a using block.

Dave

Morten Marquard said...

Hi Dave,
Thanks a lot for all the detailled work. I'll review my logic and post back comments here whether I can get it working or not.

Just a bit strange that you have to modify the "Title" property from "Title" to "vti_Title" to get it working!
Morten

Dave Hunter said...

Probably because its the old way of adding files. I've recently been through the same pain recently and choose to use the following code instead

// add the file
SPFile file = docLib.RootFolder.Files.Add(newFileName, upload.PostedFile.InputStream);

// get the list item for that file
SPItem item = file.Item;

// set the content type id
item["Content Type ID"] = currentSite.AvailableContentTypes[ContentTypeName].Id;
item.Update();

The code above is aware of content type and uses the new calls instead of using SPWeb.Files.Add. By the way docLib is a SPDocumentLibrary.

Hope this helps
Dave

Dave Hunter said...

The difference in my code is that I retrieve the SPFile, get its item and then set the properties. You will be able to set the title using:

// add the file
SPFile file = docLib.RootFolder.Files.Add(newFileName, upload.PostedFile.InputStream);

// get the list item for that file
SPItem item = file.Item;

// set the content type id
item["Title"] = "My Title";
item.Update()

Anonymous said...

It is remarkable, rather valuable answer