Jan 29

List Item Attachments – Handling the uploads manually.

Uploading files into SharePoint from code is not an onerous task. The hard part comes from creating the items and metadata around the file that you wish to upload.

One area that is really easy to work with is List item Attachments. If you examine the SPListItem class, you’ll find mention of an SPAttachmentsCollection available from SPListItem.Attachments.

If you have ever uploaded attachments onto a list (Note: NOT a document library..the .Attachments will always be null for document libraries!), then you’ll be used to the funny URL that attachments get given. Something alon the lines of Lists/Listname/Attachments/1/filename.jpg. So how does this URL breakdown? Well /Lists/Listname is pretty straight forward, It’s the rootfolder of your particular SPList. The folder attachments is a standard name put in place by SharePoint, and the integer is the index of the item that we’re attaching to.

Excellent I hear you cry, I can just build that from the various URL’s I know.. Hang on a minute!! Just this once the SharePoint object model helps you with SPListItem.Attachments.UrlPrefix. This little string holds everything you need right up to the filename, all you need to do is tack on the filename you’re uploading and it gives you the full url for the attachment..

A couple of gotchas to watch out for.. Make sure you check that the file doesn’t already exist in the attachment collection, and also from a Security point of view, we need to check the file we’re uploading doesn’t come from the list of blocked file types!

So time for some code.

I’ve written a simple application page that can be connected to the Edit Control Block menu of any List using the techniques in (this post). Not the most earth shattering use here, after all you can add an attachment in the edit screen, but it gets the idea across.

First of all the .ASPX page. This page consists of some labels, a file upload control and an OK button to trigger the page post back.

<%@ Assembly Name="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Assembly Name="Your code behind signature goes here!"%>

<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" Inherits="Namespace.application.FileUploadTest"
                  EnableViewState="false" EnableViewStateMac="false" %>

File upload test File upload test

Rather than post all of the code behind, I’ll just choose the important snippets that should give you the idea of what we’re attempting..

Note: For all of the methods here to work, you must have at least the following using statements in play:-

using System.Collections.ObjectModel;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

The first thing we do is check if there are already any attachments on the item that I’m editing. if there are, then we list them in one of the page labels as clickable links.

if (sourceItem.Attachments != null)
//Get the generic prefix required for all attachments.
string strAttachmentURLPrefix = sourceItem.Attachments.UrlPrefix;

lblExistingAttachments.Text = "Current Attachments on this Item:-

"; //Need to list existing attachments as URL's. SPAttachmentCollection colAttachments = sourceItem.Attachments; for (int i = 0; i < colAttachments.Count; i++) { if (fileUploadField.HasFile == true && fileUploadField.FileName == colAttachments[i]) { boolAttachmentFound = true; } //The html tags here get rendered by wordpress for some reason.. //Just take the tildes out. lblExistingAttachments.Text += "<~a ~href =\"" + strAttachmentURLPrefix + colAttachments[i] +"\">" + colAttachments[i] + "<~/a><~br/>"; } }

Note, As we load the attachments list, I’m also checking it against the file upload control to check if our chosen file is already attached. (This only makes sense during a postback, so the if statement uses the fileUploadField.HasFile to ensure we don’t test an empty string.) If it does, then we set a tracking boolean.

The next section of code sits within an If statement checking that we are in a PostBack, that the fileUploadField has a file selected and most importantly that the filetype selected is valid for this web farm. (This is the verifyFileExtension method that you can see..)

if (boolAttachmentFound == false)
if (verifyFileExtension(fileUploadField.FileName))
sourceItem.Attachments.Add(fileUploadField.FileName, fileUploadField.FileBytes);
throw new ArgumentException(“That file type has been blocked by the site administrators.”);
throw new ArgumentException(“That file already exists as an attachment to this item. Please rename the attachment and try your update again.”);

Finally, the VerifyFileExtension method to check the filename against the blocked file types stored in Central Admin.

public bool verifyFileExtension(string filename)
    Uri siteURI = new Uri(this.Site.Url);
    SPWebApplication webApp = SPWebApplication.Lookup(siteURI);

    Collection blockedTypes = webApp.BlockedFileExtensions;

    string[] fileExt = filename.Split('.');
    string strExtension = fileExt[fileExt.Length - 1];

    if (blockedTypes.Contains(strExtension))
        return false;
        return true;

Hope this helps


1 ping

  1. SpittingCAML » InfoPath forms with file attachments: one potential solution, for all InfoPath forms?

    […] My fat blog – validation of allowed file extensions […]

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>