Integrating Windows Form Click Once Application into SharePoint 2007–Part 4 of 4

(This is a series of posts covering how to include a WinForm app inside a SharePoint 2007 application, which allows users to upload batches of files to a SharePoint document library. For further info, please see Posts One, Two, and Three. All of the code can be downloaded in Post Two.)

Just a quick review of our solution, as detailed in the first three posts of this series: a Custom Action adds a menu choice to a document library’s Upload menu, which links to a Windows Form application deployed using Click Once.  The WinForms app allows the user to select files, label them with meta data, and then upload them to a SharePoint document library.  This post will cover what happens after the files are uploaded and also how we packaged everything into one SharePoint solution file, using WSPBuilder.

Web Services

If you remember from Post Two, our WinForms app calls several web service methods.  (The web methods are contained in the ListService.cs file, and are the ClickOnceSharePoint.WebService class.)


If you look at the graphic above with the solution’s files, you’ll see several files in the WebServiceCode folder.  There’s the web service itself in the ListService.cs file, there’s a dataset used to store content type info named GetContentTypes.xsd.  The other files, ContentType.cs, FieldDefinition.cs, and FileInformation.cs, are custom objects that are used to pass information between the client and the web service.

When we open the ListService.cs file, we see these web methods:

        [WebMethod(Description = "Returns a list of Content Types for the given SharePoint List")]
        public List<ContentType> GetContentTypes(String ListName, String SiteName)

        [WebMethod(Description = "Returns a list of Fields for the given Content Type for the given SharePoint List")]
        public List<FieldDefinition> GetFieldDefinitions(String ContentTypeId, String ListName, String SiteName)

        [WebMethod(Description = "Updates the meta data for a set of files in a document library")]
        public bool SetFileInformation(String ListName, String SiteName, FileInformation myFileInformation, String FolderName)

        [WebMethod(Description = "Creates a folder in the document library, or does nothing if one of that name already exists")]
        public bool CreateFolder(String ListName, String SiteName, String FolderName)

The first web method, GetContentTypes(), returns the available content types for the doc library, then once the user chooses a content type, GetFieldDefinitions() is called to get the fields (aka: columns in the SharePoint doc library; aka: meta data) and their corresponding data types. The app then populates the choices on the screen with the information that it retrieves.

Our user fills in the meta data, selects the files to upload, and then clicks upload.  The app uploads each file and then calls the SetFileInformation() web method, which requires a list of FileInformation objects.  Here is the FileInformation class:

using System.Collections.Generic;
using System.Collections;
using System;

namespace Express.StorePortal.WebService
    public class FileInformation

        public List<string> FileName { get; set; }

        public List<FileField> FileFields { get; set; }

        public string ContentTypeId { get; set; }
        public string ContentTypeName { get; set; }

        public bool AllViewersCanAccess { get; set; }
        public List<String> RolesThatCanView { get; set; }

    public class FileField
        public string DisplayName { get; set; }
        public string InternalName { get; set; }
        public string Value { get; set; }


As you can see, the list of data sent to the web service includes the filename, the SharePoint columns (FileField), and the security permissions that the file should have. (See Post Two of this series for more information about the application.)

If there is an error, or the user is uploading a lot of files, there is a possibility that another user would see these uploaded files in the library before the web service has had a chance to populate their columns.  To handle this, we configured the views on our list to only display files that had their values set.  We also didn’t allow our users to create their own views for this library, so we reduced the chances that users would see files that aren’t labeled.

Packaging everything in a WSP

The last part of solution is deployment.  We used WSPBuilder, integrated with Visual Studio 2008, to organize and build the code into SharePoint solutions files (*.wsp).  We have two projects in our solution.  The first project is “ClickOnceApp”, which as the name would suggest, is the Windows Form click once application that runs on the client.  The second project is “ClickOnceSharePoint” which contains the rest of the code and artifacts (custom actions, web services, images, etc).  It also contains the compiled version of the ClickOnceApp, in the 12/Template/Layouts/ClickOnceApp folder:


We did this by telling the ClickOnceApp to save the build output to this folder in the second project.  This is done either in the project properties or in the first screen of the publish wizard:


When we tell WSPBuilder to build the .wsp file, it includes the ClickOnceApp files in this folder.  This allows us to deploy the click once app right along side any other artifacts and .dll’s and it works flawlessly.

Final Summary

My first suggestion to anyone thinking of doing a similar solution, is to look into Silverlight first. Silverlight is easier to deploy and is also supported across many platforms.  One of the bigger issues we had to deal with was ensuring that the appropriate .Net runtime was already on the client computers that would need to run this app.

You might also want to think about having a separate .wsp for the click once app.  This would allow you to deploy an updated click once app without having to include new web service code.

And with that, our Integrating Windows Form Click Once Application into SharePoint 2007 blog post series is concluded.

Print | posted @ Monday, September 6, 2010 8:30 PM