How to set the content type of a new file in a document library, when uploading said file through code (aka longest and most convoluted blog title to date)

I’m on a project that’s very close to being implemented in production. For the final go-live we will be uploading a bunch of files (about 700) into a document library. There are two content types in our document library, SPI Documents and SPI Drawings. Uploading the files directly into the document library will pick the default content type. How do we change it to use the second content type, instead of the default, for some of the files?

I did some searching around and essentially what you have to do is set the ContentTypeID and Content Type fields, although my initial tries didn’t seem to work. Turns out when you’re working on a document library there’s an extra hoop you have to jump through to get it working. You have to set the content type on the SPListItem item that belongs to the SPFile object you upload, then call SystemUpdate() on that object, before finally calling Update() on the SPFile object to save it.

Here’s some rough code to demonstrate:

// destinationWeb is an SPWeb object representing the web where we want to store the files
// destinationUrl is a string representing the URL location where we want to store the files

DirectoryInfo directory = new DirectoryInfo("C:\Temp");

foreach(FileInfo sourceFile in directory.GetFiles("*", SearchOption.TopDirectoryOnly))
    using(FileStream fileStream = sourceFile.Open(FileMode.Open, FileAccess.Read))
        SPFolder folder = destinationWeb.GetFolder(destinationUrl);

        // After the file has been sanitized, let's add it
        SPFile newFile = folder.Files.Add(sourceFile.Name, fileStream, true);

        // Check whether we should make it a drawing
        if (sourceFile.Name.ToLowerInvariant().EndsWith(".dwf"))
            SPContentType spiDrawing = newFile.Item.ParentList.ContentTypes["SPI Drawing"];

            newFile.Item["ContentTypeId"] = spiDrawing.Id;
            newFile.Item["Content Type"] = spiDrawing.Name;

            // We need to update the item, before we update the file
            // Item.Update() doesn't seem to do it, so we're calling SystemUpdate() instead


Taking a look at the code, we’re not doing anything¬†particularly¬†fancy here. We open up a directory and iterate through each file getting the stream of said file. We then upload the file using the stream to the document library. Then we do a quick check on the file name and if it ends with “.dwf”, we lookup the SPI Drawing content type object and pass it into the respective fields. Next we do a SystemUpdate() on the SPListItem, before we finally call Update() on the SPFile object.

As mentioned in the comment, newFile.Item.Update() doesn’t seem to do the trick which is why I’m calling newFile.Item.SystemUpdate() instead. I’m not quite sure why, but if anyone has any insight I’d love to hear it.

This is for SharePoint 2007, but I would imagine that SharePoint 2010 is fairly similar.

One comment

Leave a Reply

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