5.1. Object Model

The beginnings of any object model exploration should start with a basic understanding of what you're working with. Windows SharePoint Services delivers to developers an object model comprising 30 public namespaces in 10 assemblies. Taken from the Windows SharePoint Services SDK (at http://msdn2.microsoft.com/en-us/library/ms453225.aspx), the following table contains a subset of this list of public namespaces, which assembly files they're each contained in, and a short description of what each namespace offers to developers. For the full list, please refer back to the WSS SDK documentation.

NameAssemblyDescription
Microsoft.SharePointMicrosoft.SharePoint (in Microsoft.SharePoint.dll)Provides types and members for working with a top-level site and its subsites or lists
Microsoft.SharePoint.AdministrationMicrosoft.SharePoint (in Microsoft.SharePoint.dll)Provides administrative types and members for managing a Microsoft Windows SharePoint Services deployment
Microsoft.SharePoint.DeploymentMicrosoft.SharePoint (in Microsoft.SharePoint.dll)Provides types and members for importing and exporting content between Windows SharePoint Services web sites
Microsoft.SharePoint.MeetingsMicrosoft.SharePoint (in Microsoft.SharePoint.dll)Provides types and members that can be used to customize Meeting Workspace sites
Microsoft.SharePoint.MobileControlsMicrosoft.SharePoint (in Microsoft.SharePoint.dll)Provides server controls for rendering the mobile forms and view pages used in SharePoint lists
Microsoft.SharePoint.NavigationMicrosoft.SharePoint (in Microsoft.SharePoint.dll)Provides types and members for customizing the navigation structures and site maps of SharePoint web sites
Microsoft.SharePoint.WorkflowMicrosoft.SharePoint (in Microsoft.SharePoint.dll)Provides types and members for associating, initiating, and managing workflow templates and instances

Thirty namespaces sounds like a daunting learning curve, but an understanding of what you're trying to accomplish can help you target which namespace(s) you'll need in your code. Another feature of the SharePoint object model that helps you write code is that the WSS OM is extremely hierarchical—you can navigate from higher-level objects such as the SPSite object all the way down to the SPListItem object and back.

The WSS SDK illustrates this navigation (http://msdn2.microsoft.com/en-us/library/ms473633.aspx) with Figure 5-1 and a description of classes and properties.

Figure 5.1. Figure 5-1

  • Each SPSite object represents a site collection and has members that can be used to manage the site collection. The AllWebs property provides access to the SPWebCollection object that represents the collection of all web sites within the site collection, including the top-level site. The Microsoft.SharePoint.SPSite.OpenWeb method of the SPSite class returns a specific web site.

  • Each site collection includes any number of SPWeb objects, and each object has members that can be used to manage a site, including its template and theme, as well as to access files and folders on the site. The Webs property returns an SPWebCollection object that represents all the subsites of a specified site, and the Lists property returns an SPListCollection object that represents all the lists in the site.

  • Each SPList object has members that are used to manage the list or access items in the list. The GetItems method can be used to perform queries that return specific items. The Fields property returns an SPFieldCollection object that represents all the fields, or columns, in the list, and the Items property returns an SPListItemCollection object that represents all the items, or rows, in the list.

  • Each SPField object has members that contain settings for the field.

  • Each SPListItem object represents a single row in the list.

The extremely comprehensive object model is very powerful and bears some investigation into each of the namespaces offered. There isn't space to do that in this chapter, but you will take a look at the largest and most commonly used namespace, Microsoft.SharePoint.

5.1.1. Microsoft.SharePoint

The Microsoft.SharePoint namespace is by far the most commonly used. Contained in the Microsoft.SharePoint.dll, this namespace exposes more than 220 public classes, 9 interfaces, 8 public structures, and over 70 different enumerations. This is the namespace you will turn to in order to find objects like the SPWeb, the class that represents a single SharePoint web site, and the SPList, the class that represents a single list in a SharePoint web site. In fact, for practically all of the user interface concepts in SharePoint such as sites, features, lists, templates, users, roles, and alerts, you'll find the class corresponding to that concept in the Microsoft.SharePoint namespace.

Here is some sample code demonstrating possible uses for this namespace. You'll write a Windows Forms application that creates a new SharePoint site, creates a list in that site, adds a column to the list, and finally adds an item or two to that list.

For the purpose of this and all code demos presented in this chapter, the Visual Studio development environment and the SharePoint server environment are one and the same. While the code can be written in either Visual Basic or in C#, I've called my application OMExample1 and I've written it in C#. My server's top-level site is http://localhost.

  1. Open Visual Studio 2005, and create a new Windows Application project.

  2. Once you have a new application project, add a reference to the Microsoft.SharePoint.dll so that you can use the namespaces it provides.

  3. As in the example in Figure 5-2, right-click on the References folder and select Add Reference to get the Add Reference dialog.

  4. Pick the Windows SharePoint Services component, and click OK. Now you can begin actually manipulating the form's elements and editing the code.

Rename the form from Form1 to SPMaintForm. Then place the controls from the following table onto the form and arrange them so that your form looks somewhat like the form in Figure 5-3.

Control TypeControl NameDescription
TextboxNewSiteNameTextBoxEntry field for users to type in the site's name
LabelNewSiteDirectionsLabelDirections to the user about the new site name text box
LinkLabelNewSiteLinkLabelHyperlink to the newly created site
ButtonCreateNewSiteButtonClick to create a new site with the user-supplied name and URL.
GroupBoxNewSiteNameGroupBoxContains all controls dealing with the creation of a new SharePoint web
TextboxListNameTextBoxEntry field for users to type in the new list's name
LabelListNameLabelDirections for users
GroupBoxNewListGroupBoxContains all controls involved in the creation of a new list with a custom field type
TextBoxColumnNameTextBoxEntry field for users to type in the name for the new list field
LabelColumnNameLabelDirections for users
LabelColumnTypeLabelDirections for user
Radio ButtonSingleLineRadioButtonCheck for a single-line (Text) column type.
Radio ButtonMultiLineRadioButtonCheck for a multiple-line (Note) column type.
Radio ButtonNumberRadioButtonCheck for a numeric (Number) column type.
GroupBoxColumnPropertiesGroupBoxContains all controls dealing with the creation of a custom column type in the new list
ButtonCreateNewListButtonClick to create a new list with the given name and add a named column of the specified type to the new list.
TextboxNewItemTitleTextBoxEntry field for users to input the title of the new item
TextboxNewItemCustomDataTextBoxEntry field for users to input the custom data of their choosing
LabelNewItemTitleLabelDirections for users
LabelCustomColumnDataLabelDirections for users
ButtonAddItemButtonClick to add a new item to your new list in your new site.
GroupBoxNewListItemGroupBoxContains all controls involved in the creation of a new list item

Figure 5.2. Figure 5-2

Figure 5.3. Figure 5-3

Now look at the salient portions of the code in Listing 5-1. The entire solution is provided on the companion web site, at www.wrox.com.

Example 5.1. Listing 5-1
private void CreateNewSiteButton_Click(object sender, EventArgs e)
        {
            ...
            {
                // Get a reference to the top-level site.
                SPSite TopLevelSite = new SPSite("http://localhost");
                SPWeb SharePointWebInstance = TopLevelSite.OpenWeb();
                // Grab our current site's template for use below.
                string CurrentSiteTemplate = SharePointWebInstance.WebTemplate;

// SharePoint is fond of throwing exceptions so be sure to do this
in a Try..Catch.
                try
                {
                    ...
                    // Add a new item to the top level site's Webs collection.
                    SharePointWebInstance.Webs.Add(NewSiteNameTextBox.Text,
                                                   NewSiteNameTextBox.Text,
                                                   "New website added with the
OMExample1 test application",

(UInt32)System.Globalization.CultureInfo.CurrentCulture.LCID,
                                                   CurrentSiteTemplate,
                                                   false,
                                                   false);
                    ...
                }
                catch (Exception ex)
                {
                    ...
                }
                finally
                {
                    // Free up your resources!
                    TopLevelSite.Close();
                    SharePointWebInstance.Dispose();
                }

5.1.1.1. SPSite

This CreateNewSiteButton click event handler contains the bulk of your code for creating a new site. First, you have to establish a reference to the site under which you plan to add a new site. Using the SPSite class and the URL to your top-level site, you get an object that represents the entire site collection. Given your site collection object, you can open a specific web via the OpenWeb() method. You could have identified a site under your top-level site had you passed in a GUID or a site-relative URL, but by not passing in any parameters you elected to open the top-level site at http://localhost. Other interesting methods of the SPSite class include DoesUserHavePermissions(), GetRecycleBinItems(), RecalculateStorageSpaceUsed(), and of course, Delete() and Close().

5.1.1.2. SPWeb

Once you have opened your top-level web, you discover which template was used so you can use the same template for a consistent look and feel in your new site. Each SPWeb object contains a Webs collection that represents all of its subsites. Adding to this collection adds a new subsite. Notice that you pass a localization ID (frequently hard-coded to 1033 in the WSS SDK examples). This localization ID represents the locale folders under the 12 Hive (typically found at C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12). Where you pass in the site template of the current site, you could specify any of the templates in the SiteTemplates directory (..12TEMPLATESiteTemplates) by name, such as "SPSNEWS" or "PUBLISHING". If you create custom site templates, this is where you can specify your own template's name to dynamically create new sites of your own design. Other interesting methods of the SPWeb class include DoesUserHavePermissions(), GetSubwebsForCurrentUser(), SearchListItems(), and ApplyTheme().

Once you're done adding to your site collection, you need to close any open references to the SPSite and SPWeb classes. However, if you get these references as a shared resource, you should let the platform itself manage the resource to avoid access violation errors. That is to say, if you didn't declare and instantiate the SPWeb object, as would happen if you called SPControl.GetContextWeb, then you cannot call the Dispose method. There is more information about correctly disposing of SharePoint objects in the "Best Practices" section of this chapter.

You've added a new site, but your demo application doesn't stop there. It goes on to create a new custom list in the newly created site and adds a new field to the list. Take a look at this process in Listing 5-2.

Example 5.2. Listing 5-2
private void CreateNewListButton_Click(object sender, EventArgs e)
        {
            ...
            // gGet a reference to your newly created site.
            SPSite TopLevelSite = new SPSite("http://localhost");
            SPWeb NewSPWebInstance = TopLevelSite.OpenWeb(NewSiteURL);
            // Using the web's Lists property, get a reference to the collection of lists in the site.
            SPListCollection SiteLists = NewSPWebInstance.Lists;
            try
            {
                // Add a new SPList to the Lists collection.
                NewListID = SiteLists.Add(ListNameTextBox.Text.Trim(),
                                          "New list added dynamically via the OMExample1 sample application",
                                          SPListTemplateType.GenericList);
                try
                {
                    // Get a reference to our new list.
                    SPList NewSPListInstance = NewSPWebInstance.Lists.GetList(NewListID,
                                                                              false);
                    // Get the fields collection from our new list so we can add to it.
                    SPFieldCollection Fields = NewSPListInstance.Fields;

                    // Pick which type of field to create, default to single line text.
                    SPFieldType UserChosenFieldType = SPFieldType.Text;
                    if (SingleLineRadioButton.Checked)
                    {
                        UserChosenFieldType = SPFieldType.Text;
                    }
                    else if (MultiLineRadioButton.Checked)
                    {
                        UserChosenFieldType = SPFieldType.Note;
                    }
                    else if (NumberRadioButton.Checked)
                    {
                        UserChosenFieldType = SPFieldType.Number;

}
                    ...
                    try
                    {
                        // Add a new field of the chosen type to the fields collection.
                        string NewSPFieldInstance = Fields.Add(ColumnNameTextBox.Text,
                                                               UserChosenFieldType,
                                                               true);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error encountered attempting to add a new field" +
                                        Environment.NewLine +
                                        ex.Message);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error encountered attempting to identify the new list" +
                                    Environment.NewLine +
                                    ex.Message);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error encountered attempting to create a new list" +
                                Environment.NewLine +
                                ex.Message);
            }
            finally
            {
                TopLevelSite.Close();
                NewSPWebInstance.Dispose();
            }
            ...
        }

5.1.1.3. SPListCollection

This function starts out by going back to the top-level site to try to find your current web. Notice this time that when you call the OpenWeb() function, you are passing in a string which is the relative URL from the top-level site. This enables you to open the site you just created. The SPWeb NewSPWebInstance object has a property called Lists, which holds a collection of all the lists contained in this site. Adding a new SPList object to this collection adds a new list to the site. Likewise, removing a list from a collection would remove it from a site. Another method of finding a specific list is to start with the SPContext's AllWebs[] property and passing in the desired site name as an index to retrieve the specific SPWeb object. Once you have the specific SPWeb, use the SPWeb.Lists[] property to retrieve a handle to the desired list. Note that the SPContext object refers to the current HTTP request to a SharePoint site and is best used in web applications.

SPList currentList = SPContext.Current.List;
SPWeb currentSite = SPContext.Current.Web;
SPSite currentSiteCollection = SPContext.Current.Site;
SPWebApplication currentWebApplication = SPContext.Current.Site.WebApplication;

Given the SPWeb object, the SPListCollection.Add() method creates a new list and accepts the name, description, and list type as arguments and returns the GUID of the newly created list. This is extremely helpful because to do any further operations on the list itself, you'll need this GUID.

5.1.1.4. SPList

Given the GUID returned by the SPListCollection.Add() method, you can instantiate a reference to your newly created list in the form of a SPList object and manipulate it's properties. For the purposes of this example, you're going to add a custom column based on user input. Other interesting methods on the SPList object include DoesUserHavePermissions(), IsContentTypeAllowed(), and WriteRssFeed().

5.1.1.5. SPFieldCollection

Every SPList object has a Fields property, which contains a collection of SPField objects associated with a particular list. The code in Listing 5-2 retrieves this collection for use because, like all of the other SharePoint collection properties you've worked with so far, adding to the collection adds a new field.

5.1.1.6. SPFieldType

Before you add a new field to the SPFieldCollection, check the user input portions of your application to see which SPFieldType the user selected. Using the SPFieldType enumeration, you are able to set a field to one of thirty-two options, including the Text, Note, and Number you're using here. Other options include CrossProjectLinks for Meeting Workspaces and Users to represent SharePoint users.

Now that you've created a new web and put a new list with a custom field into that list, do the work of adding an item to that list. Listing 5-3 illustrates just that task.

Example 5.3. Listing 5-3
private void AddItemButton_Click(object sender, EventArgs e)
        {
            ...
            // Get a reference to our newly created site.
            SPSite TopLevelSite = new SPSite("http://localhost");
            SPWeb NewSPWebInstance = TopLevelSite.OpenWeb(NewSiteURL);
            // Using the web's Lists property, get a reference to the collection of lists in the site.
            SPListCollection SiteLists = NewSPWebInstance.Lists;
            try
            {
                // Find our list.
                SPList TargetList = SiteLists.GetList(NewListID,
                                                      false);
                // Get the ListItems collection from the web.
                SPListItemCollection ListItems = TargetList.Items;
                try

{
                    // Add a new ListItem.
                    SPListItem NewItem = ListItems.Add();
                    // Populate the title field.
                    NewItem["Title"] = NewItemTitleTextBox.Text;
                    // Check the type of the custom field.
                    double NumberField = 0;
                    if (NumberField.GetType() != NewItem.Fields[NewFieldName].FieldValueType)
                    {
                        // If we're a text type of field, assign the text value of the text box.
                        NewItem[NewFieldName] = NewItemCustomDataTextBox.Text;
                    }
                    else
                    {
                        // If our field is a number, we must convert the typed value to a double.
                        Double.TryParse(NewItemCustomDataTextBox.Text, out NumberField);
                        NewItem[NewFieldName] = NumberField;
                    }
                    // Persist changes to the SharePoint content database.
                    NewItem.Update();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error encountered attempting to add a new item to the list" +
                                    Environment.NewLine +
                                    ex.Message);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error encountered attempting to identify the new list" +
                                Environment.NewLine +
                                ex.Message);
            }
            finally
            {
                TopLevelSite.Close();
                NewSPWebInstance.Dispose();
            }
            ...
        }

5.1.1.7. SPListItems

Again, in Listing 5-3, you start with the now familiar process of obtaining a reference to your web. You drill down through the SPWeb to the list. The SPList object predictably exposes an Items collection, which contains all of the SPListItem objects associated with this particular list. However, adding a new item to a list is not as simple as calling SPList.Items.Add(). Well, actually it is that simple, but after you've added the SPListItem, you need to populate the fields and call the SPListItem.Update() method. As you see in the code above, the SPListItem is returned by the SPList.Items.Add() function. Given this reference to the list item, you can populate the fields using an indexer to specify which field is being updated. Thanks to your user input selection of text or number, you have to handle attempts to add numbers to your custom field. It is worth noting here that SPFieldType.Number maps to a System.Double. For a full list of these mappings between SharePoint SPFieldTypes and .NET types, refer to the following table, which can also be found in the Windows SharePoint SDK. Once both fields have been set to your desired values, you call the SPListItem.Update() method to save the changes to the SharePoint content database. Following that, you dispose of any open references that need to be freed.

NameFormat
AttachmentsSystem.Boolean
BooleanSystem.Boolean
CalculatedN/A
ChoiceSystem.String
ComputedN/A
CounterSystem.Int32
CrossProjectLinkSystem.Boolean
CurrencySystem.Double
DateTimeSystem.DateTime
GridChoiceSystem.String
GuidSystem.Guid
IntegerSystem.Int32
LookupSystem.String
MaxItemsSystem.Int32
ModStatSystem.Int32
MultiChoiceSystem.String
NoteSystem.String
NumberSystem.Double
RecurrenceSystem.Boolean
TextSystem.String
ThreadingSystem.String
URLSystem.String, System.String
UserSystem.String
NoteSystem.String

With the code complete, you can run the application.

After filling in all of the required user input fields and pressing all the buttons in the right order, you should get a new SharePoint web under your top-level site.

  1. Click on the hyperlink on the OMExample1 form to go to the new web's home page. Your screen should look something like Figure 5-4.

    Figure 5.4. Figure 5-4
  2. Click on the Lists link in the Quick Launch bar to verify that the new list has been created, as shown in Figure 5-5

  3. Open the new list to verify that the data has, in fact, been added, as shown in Figure 5-6.

  4. Open the item to validate that the data looks right and that the custom field is of the type you expect. In my sample run I chose to use a MultiLine field type, shown in Figure 5-7.

    Figure 5.5. Figure 5-5

    Figure 5.6. Figure 5-6

    Figure 5.7. Figure 5-7

This fairly trivial example only scratches the surface of the enormous programming power offered by the Microsoft.SharePoint namespace. You've looked at only 6 of the 220 public classes, 2 of the 70 different enumerations, and none of the public interfaces or structures. Learn more about the Microsoft.SharePoint namespace in the Windows SharePoint Services SDK: http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.aspx.

5.1.2. Microsoft.SharePoint.Workflow

One of the most exciting new namespaces in SharePoint v3 is the Workflow namespace. Workflow is a new .NET 3.0 technology designed to support long running transactions with multiple points of interaction. While Windows SharePoint Services comes with a few built-in workflows, you have the ability to create your own workflows using the Microsoft.SharePoint.Workflow namespace. This topic is so deeply intensive that we've devoted an entire chapter to it later in the book, Chapter 15.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.2.78