If you haven’t heard of Office Open XML don’t be surprised. I hadn’t until a couple of months ago. In short it is a standardization of the Office document models which allows for more flexible development methods. You no longer need to have an instance of your target Office application running on a server in order to generate Word, Excel or PowerPoint documents. This is also the reason that all of the Office file extensions have a “x” suffix these days.
Office Open XML files are actually zip files. This is to allow verbose XML files and required associated documents to be kept as a single package instead of in a binary format. Given that we are talking about XML files in a zip archive, you can really program against Office Open XML documents simply by knowing the schema definition. But who wants to do that if someone has already given you a strongly typed API library?
This is where the Open XML SDK 2.0 comes in. This library gives you strongly typed classes which represent the parts that make up documents. This in turn makes reading you code easier than simply using a XMLDocument to modify the file.
When working with the XML of a document I have found it hard to find a compact reference of element types. Of course you can always refer to the verbose ISO standards document (all 5572 pages worth). Going forward I hope to have some helpful tips for working with the powerful but under-documented technology. Stay tuned.
There is nothing earth shattering here. I was just putting together a set of snippets to make life a little easier while developing SharePoint and Office Open XML projects. My search for information crossed a lot of different sites. MSDN has a number of articles about all the features of creating and managing snippets. Below is a compilation of the basics around creating these little helpers. Hopefully it is a little more detailed in the whys then MSDN content.
Creating A Snippet File
Snippet files are really just XML files with a .snippet extension. The main thing is the schema that is applied and the available tags. I have found a couple of namespaces listed for the CodeSnippets tag, but the following seemed to work most reliably.
Once you have that in place you can start working on the header information. These include your title, author, description and shortcut. Most of this shows up in the snippet manager, but the shortcut allows a developer to type the shortcut text and hit tab to invoke the snippet.
<Description>Inserts my favorite code</Description>
Now we get to the meat of the snippet. The snippet itself is broken into two parts: the declaration and the code.
The declaration allows you to define the parts of your snippet which the developer will need to replace with their own identifiers. Declarations themselves come in two flavors: literals and objects. While this should be pretty self-explanatory lets be thorough. Literals are just that. They are strings that can be inserted at the specific location. These are perfect for letting the developer insert URLs or string defaults in declarations. Objects on the other hand have a type specified for them.
For all declarations you are allowed to add a tooltip so the the developer understand the usage of your snippet. Below are examples of both kinds of declarations.
Replace with your variable name
Replace with the Web URL
Once you have the declarations defined you simply add you code as you would normally see it. The only catch is that you will need to create a token in the code for each declaration offset by dollar characters ($).
using (SPSite $Var$ = new SPSite($Url$))
Using The Snippet Manager
The snippet manager allows you to import your files and make them available within the Visual Studio environment. One thing it does not seem to allow you to do is delete individual snippet files. It has the option to delete a directory which is great as long as you use the Add feature which allows you to bring in an entire folder of snippets at one time. Otherwise all snippets added with the Import feature get put under the My Code Snippets folder.
And that about covers the basics. Good coding …
Now how many people understand the reference in the title. I don't know if it something that is still done today, but it was a big deal when we moved from Win16 to Win32. I essentially allowed 16bit applications to run on a 32bit Windows machine.
Today I was reminded of this as I removed Windows 7 64bit from my machine because certain applications still do not work on that platform. Event through 64bit processors and even operating systems have been around for a while they still haven't achieved critical mass. This means that for a while yet we will still be playing Russian Roulette when we install Win7 64bit.
For me, I spent the afternoon rebuilding my system on 32bit Windows 7 because of one incompatibility that was risking my project. That doesn't mean that there is something wrong with the platform. It is just ahead of its time. I'm sure I'll be re-installing it soon enough.
SharePoint has been around for quite some time. I first worked with it in its original version in 2001. And so began a love hate relationship that has lasted these many years.
Recently I have been spending a significant amount of time writing custom web parts. Below are a number of notes I have accumulated while rediscovering what SharePoint can do. I don’t claim that these are best practices, only that they have worked for me.
Creating web parts for WSS 3.0 or MOSS 2007 requires Visual Studio 2005 or Visual Studio 2008. There is a downloadable package Visual Studio Extensions for Windows SharePoint Services 3.0. The problem with this particular tool is that it requires that you develop on a machine with Windows Server 2003 or Windows Server 2008 as an operating system. Developing on a stand alone desktop/laptop while referencing the main SharePoint assembly can be much simpler. It is a trade off between licenses issues and portability challenges versus a lack of productivity tools. For this discussion we will assume a stand alone, non-server environment.
WSPBuilder is a CodePlex project for creating SharePoint solution files. Besides packaging web parts it is also a tool for packaging features and workflows. The tool can be downloaded from the following location:
Starting A Web Part
Web Parts are really just specialized web server control. That being said, creating a web server control is the perfect place to start and then modify it for SharePoint. Alternately you could start with an ASP.NET web part. The caution here is that they implement a different set of events.
One of the first things you will need to do is to change the class that the control inherits from to Microsoft.SharePoint.WebPartPages.WebPart.
Additionally you will need to add the following import statements:
Adding Web Part Properties
Web Part Properties are the definition of the settings which allow you to configure a web part once you have placed it on a page. They start out the same as any C# property with a getter and setter. The main difference are the attributes that are applied to the property.
[Category("User Creation Settings")]
[FriendlyName("Role Provider Name")]
[Description("Name of the membership role provider")]
[XmlElement(ElementName = "roleProvider")]
public string ProviderName
_ProviderName = value;
Adding controls to a web part
There isn’t a designer for creating web parts. The process reminds me of C++ MFC development. You have to define, instantiate and position all of your controls through code. I have seen some possible short cuts be first creating user controls, but the process seemed a little hackish and I haven’t tested it yet.
First you should define the controls globally in your class.
Once you have your controls defined you instantiate them in the CreateChildControls override method. This is also the point where you wire up any event handler methods. The code below is an example of the techniques that can be used.
_FirstName= new TextBox();
_FirstName.CssClass = "my-textbox";
_OptionType= new DropDownList();
_CreateUser = new Button();
_CreateUser.CssClass = "my-button";
_CreateUser.Text = "Create User";
_CreateUser.Click += new EventHandler(_CreateUser_Click);
_Message = new Label();
_Message.CssClass = "my-errorMessage";
The last step in order to display controls for use in your web part is to implement the RenderContents override method. This method uses a HtmlTextWriter object to render the tags for the UI of your web part. The most straight forward, although not necessarily the simplest, way to do this is to write out the text of your layout tags and them pass the writer object to your controls so that they can render themselves. Alternately you can do your layout entirely through rendering controls which represent all of your resulting HTML tags. Below is an example of the first approach.
Essential SharePoint Objects
The most important classes within the SharePoint object model represent the hierarchy of the SharePoint. These are the SPWeb and SPSite classes. SPWeb represents a SharePoint web application as you would configure in Central Administration. SPSite represents a site collection.
You do not always have to instantiate these classes explicitly, although there are some cases where that is a requirement.
Adding users to security groups
Managing SharePoint security for end users can be very confusing. One way to alleviate this burden is to create a web part that abstracts away the details. The main class used to facilitate this capability is SPGroup.
There are two critical things to note in the code below. The first is the fact that it is written as an inline delegate to elevate the privileges of the current user.
The second thing to note is the use of the AllowUnsafeUpdates property of the SPWeb object.
SPSite newSite = new SPSite(_SiteUrl);
SPWeb web = newSite.OpenWeb();
web.AllowUnsafeUpdates = true;
SPGroup candidateGroup = web.Groups[_SharepointGroup];
candidateGroup.AddUser(fullyQualifiedUserID, _Email.Text, userName, string.Empty);
Adding items to lists
The topic of lists covers both SharePoint Lists and Document Libraries. They are both essentially list, except for one puts more emphasis on attachments than the other. Because of this they can be treated the same in many respects. The code below adds a file to a document library and then sets values for columns on that list.
SPFolder folder = web.GetFolder(_Folder);
SPFile sourceFile = web.GetFile(_TemplateUrl);
string folderUrl = folder.ServerRelativeUrl + "/";
string fileName = _BaseFileName + ".xml";
sourceFile.CopyTo(folderUrl + fileName);
SPFile newFile = folder.Files[fileName];
newFile.Item["First Name"] = _FirstName.Text;
newFile.Item["Last Name"] = _LastName.Text;
newFile.Item["Full Name"] = _LastName.Text + ", " + _FirstName.Text;
newFile.Item["Preferred Name"] = _PreferredName.Text;
newFile.Item["Appointment Type"] = _OptionType.SelectedItem.Text;
Notice that the last line calls the Update method on the item. If this call is not made then your changes will not be saved.
Deploying SharePoint web parts can be tedious and problematic. While installing them by hand is possible solution files make the process somewhat easier to manage. At the beginning of the paper I mentioned WSPBuilder. The WSP stands for WSS Solution Project. What these boil down to are CAB files which include deployable objects and a manifest of the contents. WSPBuilder simplifies the creation of these files.
There are two ways that this can be accomplished. Installing the WSPBuilder gives you Visual Studio extensions as well as new Visual Studio templates. The former simply packages the assembly of a project and creates safe control entries for your web.config file.
Adding the solution to SharePoint using stsadm
Once you have created a solution you need to copy it to the server that Central Admin resides on. There you will use the stsadm command line tool to install the solution. Execute the following command, making sure to modify the filename parameter value for the location you copied the wsp file to.
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>stsadm -o addsolution -filename "d:\webparts\MyWebPart.wsp"
Deploying solution through Central Admin
The only time that I have found that I needed to access Central Admin for a web part solution is initial deployment or to remove a solution.
In order to deploy the web part solution that was added during the previous section you need to navigate to Solution Management from the Operations tab in Central Admin. There you will see a list of solutions. From there click on the solution that you want to deploy and click the Deploy Solution button at the top of the screen that appears.
Upgrading a solution to SharePoint using stsadm
Interestingly, there are more parameters required to upgrade a solution then there are to install it in the first place. This is mostly due to the functions that are taken care of by the Central Admin deployment capabilities.
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>stsadm -o upgradesolution -filename "d:\webparts\MyWebPart.wsp" -name " MyWebPart.wsp" -immediate –allowGacDeployment
Note: If you do not keep the same version number for the assembly you will break any pages that already contain the web parts contained in that assembly.