5.3. Web Services

This chapter provides a tiny glimpse of the power in the SharePoint object model that you as a developer can take advantage of. Augmenting the powerful object model is a services layer that allows developers to call into the SharePoint object model from anywhere.

Best Practices Coding Techniques

As you've seen so far in this chapter, writing code for the SharePoint object model requires the instantiation of lots of objects such as SPWeb, SPSite, and more. Many of these objects implement the IDisposable interface and should be disposed of after they've been used to prevent these objects from remaining in memory.

Scott Harris and Mike Ammerlaan from Microsoft have written an excellent article outlining these best practices recommendations titled "Best Practices: Using Disposable Windows SharePoint Services Objects" (http://msdn2.microsoft.com/en-us/library/aa973248.aspx#sharepointobjmodel__otherobjectsthatrequiredisposal). Any developer interested in writing code targeting the SharePoint platform should read this article. Scott and Mike illustrate many great practices, and they warn you about the times that you shouldn't automatically dispose of every disposable object.


Whereas the object model is organized into namespaces, the web services are grouped logically into 20 different web services. The following table identifies the web services and the methods they expose:

Web ServiceDescription and LocationMethods
Admin Web ServiceProvides methods to manage site collections. http://<AdminSite>/_vti_adm/Admin.asmxCreateSite

DeleteSite

GetLanguages

RefreshConfigCache
AlertsProvides methods for working with alerts on lists and document libraries. http://<Site>/_vti_bin/Alerts.asmxDeleteAlerts GetAlerts
AuthenticationProvides methods to authenticate users to SharePoint. http://<Site>/_vti_bin/Authentication.asmxLogin Mode
CopyProvides methods for copying files to and from Share-Point sites. http://<Site>/_vti_bin/Authentication.asmxCopyIntoItems

CopyIntoItemsLocal

GetItem
Document WorkspaceProvides methods for managing Document Workspace sites and the data they contain. http://<Site>/_vti_bin/Dws.asmxCanCreateDwsUrl

CreateDws

CreateFolder

DeleteDws

DeleteFolder

FindDwsDoc

GetDwsData

GetDwsMetaData

RemoveDwsUser

RenameDws

UpdateDwsData
FormsProvides methods for returning forms that are used in the user interface when working with the contents of a list. http://<Site>/_vti_bin/Forms.asmxGetForm GetFormCollection
ImagingProvides methods that enable you to create and manage picture libraries. http://<Site>/_vti_bin/Imaging.asmxCheckSubwebAndList

CreateNewFolder

Delete

Download

Edit

GetItemsByIds

GetItemsXMLData

GetListItems

ListPictureLibrary

Rename

Upload
List Data RetrievalThe adapter service used to perform queries against sites and lists in WSS. http://<Site>/_vti_bin/DspSts.asmxQuery
ListsProvides methods for working with lists and list data. http://<Site>/_vti_bin/Lists.asmxAddAttachment

AddDiscussionBoardItem

AddList

AddListFromFeature

ApplyContentTypeToList

CheckInFile

CheckOutFile

CreateContentType

DeleteAttachment

DeleteContentType

DeleteContentTypeXmlDocument

DeleteList

GetAttachmentCollection

GetList

GetListAndView

GetListCollection

GetListContentType

GetListContentTypes

GetListItemChanges

GetListItemChangesSinceToken

GetListItems

GetVersionCollection

UndoCheckOut

UpdateContentType

UpdateContentTypesXmlDocument

UpdateContentTypeXmlDocument

UpdateList

UpdateListItems
MeetingsEnables you to create and manage Meeting Workspace sites. http://<Site>/_vti_bin/Meetings.asmxAddMeeting

AddMeetingFromICal

CreateWorkspace

DeleteWorkspace

GetMeetingsInformation

GetMeetingWorkspaces

RemoveMeeting

RestoreMeeting

SetAttendeeResponse

SetWorkspaceTitle

UpdateMeeting

UpdateMeetingFromICal
PeopleProvides methods for working with WSS Principals. http://<Site>/_vti_bin/People.asmxResolvePrincipals SearchPrincipals
PermissionsProvides methods for working with the permissions for a site or list. http://<Site>/_vti_bin/Permissions.asmxAddPermission

AddPermissionCollection

GetPermissionCollection

RemovePermission

RemovePermissionCollection

UpdatePermission
Site DataProvides methods that return metadata or list data from sites or lists in Microsoft Windows SharePoint Services. http://<Site>/_vti_bin/SiteData.asmxEnumerateFolder

GetAttachments

GetChanges

GetContent

GetList

GetListCollection

GetListItems

GetSite

GetSiteAndWeb

GetSiteUrl

GetURLSegments

GetWeb
SitesProvides a method for returning information about the collection of site templates on the virtual server. http://<Site>/_vti_bin/Sites.asmxExportWeb

GetSiteTemplates

GetUpdatedFormDigest

ImportWeb
SearchThe QueryService class is the entry point for calling the Search in Microsoft Windows SharePoint Services Query web service. http://<Site>/_vti_bin/spsearch.asmxQuery

QueryEx

Registration

Status
Users and GroupsProvides methods for working with users, roles, and groups. http://<Site>/_vti_bin/usergroup.asmxAddGroup

AddGroupToRole

AddRole

AddRoleDef

AddUserCollectionToGroup

AddUserCollectionToRole

AddUserToGroup

AddUserToRole

GetAllUserCollectionFromWeb

GetGroupCollection

GetGroupCollectionFromRole

GetGroupCollectionFromSite

GetGroupCollectionFromUser

GetGroupCollectionFromWeb

GetGroupInfo

GetRoleCollection

GetRoleCollectionFromGroup

GetRoleCollectionFromUser

GetRoleCollectionFromWeb

GetRoleInfo

GetRolesAndPermissionsForCurrentUser

GetRolesAndPermissionsForSite

GetUserCollection

GetUserCollectionFromGroup

GetUserCollectionFromRole

GetUserCollectionFromSite

GetUserCollectionFromWeb

GetUserInfo

GetUserLoginFromEmail

RemoveGroup

RemoveGroupFromRole

RemoveRole

RemoveUserCollectionFromGroup

RemoveUserCollectionFromRole

RemoveUserCollectionFromSite

RemoveUserFromGroup

RemoveUserFromRole

RemoveUserFromSite

RemoveUserFromWeb

UpdateGroupInfo

UpdateRoleDefInfo

UpdateRoleInfo

UpdateUserInfo
VersionsProvides methods for working with file versions. http://<Site>/_vti_bin/Versions.asmxDeleteAllVersions

DeleteVersion

GetVersions

RestoreVersion
ViewsProvides methods for working with views of lists. http://<Site>/_vti_bin/Views.asmxAddView

DeleteView

GetView

GetViewCollection

GetViewHtml

UpdateView

UpdateViewHtml

UpdateViewHtml2
Web Part PagesProvides methods for working with Web Parts. http://<Site>/_vti_bin/WebPartPages.asmxAddWebPart

AddWebPartToZone

AssociateWorkflowMarkup

ConvertWebPartFormat

DeleteWebPart

ExecuteProxyUpdates

FetchLegalWorkflowActions

GetAssemblyMetaData

GetBindingResourceData

GetCustomControlList

GetDataFromDataSourceControl

GetFormCapabilityFromDataSourceControl

GetSafeAssemblyInfo

GetWebPart

GetWebPart2

GetWebPartCrossPageCompatibility

GetWebPartPage

GetWebPartPageConnectionInfo

GetWebPartPageDocument

GetWebPartProperties

GetWebPartProperties2

GetXmlDataFromDataSource

RemoveWorkflowAssociation

RenderWebPartForEdit

SaveWebPart

SaveWebPart2

ValidateWorkflowMarkupAndCreateSupportObjects
WebsProvides methods for working with sites and subsites. http://<Site>/_vti_bin/Webs.asmxCreateContentType

CustomizeCss

DeleteContentType

GetActivatedFeatures

GetAllSubWebCollection

GetColumns

GetContentType

GetContentTypes

GetCustomizedPageStatus

GetListTemplates

GetWeb

GetWebCollection

RemoveContentTypeXmlDocument

RevertAllFileContentStreams

RevertCss

RevertFileContentStream

UpdateColumns

UpdateContentType

UpdateContentTypeXmlDocument

WebUrlFromPageUrl

Let's look at an example of web services in action. Consider the following scenario: You are a developer at an organization that deals with a considerable number of external clients from a variety of companies. Your organization has decided that it wants to expose a series of SharePoint extranet portals so your company's information workers can collaborate with these external clients. You've created several SharePoint groups for your users, corresponding to their company names and their department names. Your job as the SharePoint developer is to create a mechanism to automatically add these individuals to the correct SharePoint security groups.

  1. Open Visual Studio 2005, and create a new C# Class Library project called Sharepoint.Wrappers. You're creating a class library (DLL) because this lets you remain flexible in terms of how to use your code. You have the option to integrate with Windows applications or a web application.

  2. Once you have a new class library project started, your first task is to identify which web service you want to use. Right-click the Web References folder and select Add Web Reference. Since you're developing on a machine with WSS installed on it, in the Web References dialog, select the option to list the web services on this machine.

  3. From the list of web services that comes back, pick the UserGroup web service, name the web reference SharePoint.UserGroup and click OK (see Figure 5-17). Visual Studio will automatically generate a proxy class to use in the rest of your code.

  4. Under the new Web References folder in the Solution Explorer, select the Sharepoint.Usergroup reference. In the Properties window, change the URL Behavior from Dynamic to Static. This will create an app.config that points to your SharePoint site (see Figure 5-18).

    Figure 5.17. Figure 5-17

    Figure 5.18. Figure 5-18

Since you're not sure what kind of application you'll be integrating with and DLLs don't get to read their own app.config files, you'll create your own configuration file and your own config reader class. Start by adding a new XML file to the project called WrapperConfig.xml. Copy the contents of the app.config into the XML file and change it to match the sample in Listing 5-8.

Example 5.8. Listing 5-8
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
        <appSettings>
                <add key="userID" value="sampleUser" />
                <add key="password" value="Password2" />
                <add key="domain" value="SPServerDomain" />
                <add key="SharePoint.UserGroup"
value="http://localhost/_vti_bin/UserGroup.asmx"/>
        </appSettings>
</configuration>

This custom configuration file contains the URL for your SharePoint site and the user name and password of a user who has access to the web services. This config file can be read by the following class, shown in Listing 5-9.

Example 5.9. Listing 5-9
/// <summary>
        /// Summary description for Config_XmlDocument.
        /// </summary>
        public class Config
        {
                private XmlTextReader _XmlDocument = null;
                private string _uid = string.Empty;
                private string _pwd = string.Empty;
                private string _domain = string.Empty;
                private string _WebServiceURI = string.Empty;

                public string UserID { get {return _uid;}}
                public string Password { get {return _pwd;}}
                public string Domain { get {return _domain;}}
                public string WebServiceURI{ get {return _WebServiceURI;}}

        //private Config myConfig = null;

        public Config()
                {
                        // Put the DLL and config in a well-known location.
            string DLLPath = @"c:Program FilesProSharePoint07
Sharepoint.WrapperWrapperConfig.xml";
                        _XmlDocument = new XmlTextReader(DLLPath);
            // Read our config file.
                        GetCredentialsFromConfig();
                }

                private void GetCredentialsFromConfig()
            {
            // Read through the XML file to the end.             while (_XmlDocument.Read())
            {
                // If we're looking at an element.
                if (XmlNodeType.Element == _XmlDocument.NodeType)
                {
                    // If our element is a name-value pair.
                    if (2 == _XmlDocument.AttributeCount)
                    {
                        // Get the key and value.
                        string keyName = _XmlDocument.GetAttribute("key").ToString();
                        string keyValue = _XmlDocument.GetAttribute("value").ToString();

switch (keyName)
                        {
                            case "userID":
                            {
                                _uid = keyValue;
                                break;
                            }
                            case "password":
                            {
                                _pwd = keyValue;
                                break;
                            }
                            case "domain":
                            {
                                _domain = keyValue;
                                break;
                            }
                            case "SharePoint.UserGroup":
                            {
                                _WebServiceURI = keyValue;
                                break;
                            }
                        } // End switch.
                    } // End if key pair.
                } // End if element.
            } // End while.
        } // End GetCredentialsFromConfig.
    } // End class.

You'll also want to create some mechanism for storing and easily passing around information about the users you're adding and removing from SharePoint. Create a structure that looks like this:

public struct User
    {
        public string groupNames;
        public string userName;
        public string userLoginName;
        public string userEmail;
        public string userNotes;
    }

Now let's take a look at some code back in your main Sharepoint.Wrapper class. First, include the Web Reference proxy class in the using statements at the top:

using Sharepoint.Wrapper.Sharepoint.UserGroup;

Next, you'll need to establish a connection to SharePoint. This means that you'll need to pass the credentials of a user who has access to the web services. Fortunately, you've identified just such a user in your config file. Create a method called DefineCredentials that connects us to the SharePoint UserGroup web service. This has been done for you in Listing 5-10.

Example 5.10. Listing 5-10
/// <summary>
        /// Use the ConfigReader class to read our XML defined uid, pwd, and domain name for our
        /// WS user.        /// </summary>
        private void DefineCredentials(UserGroup instance)
        {
            Config _Config = new Config();
            string userid = _Config.UserID;
            string pass = _Config.Password;
            string domain = _Config.Domain;
            instance.Credentials = new System.Net.NetworkCredential(userid, pass, domain);
        }

The UserGroup proxy class, instantiated here as the object instance, has a .Credentials property. Here is where you can store your NetworkCredential. This simple mechanism, passing in the user name, password, and domain, eliminates the requirement to have the executing application be executed by administrative users. Most online examples of the Credentials property use the DefaultCredentials, but that copies the current user's credentials and that might not be sufficient.

Now that you've got access to the web services, call one. In the scenario outlined above, you need to be able to add users to multiple groups so I've implemented the User structure's groupNames string as a pipe ('|') delimited string. This enables the calling application to call the AddUserToGroups function and pass all the groups in at once. Of course, SharePoint won't be expecting that, so you'll implement some custom business logic to break apart that string, as shown in Listing 5-11.

Example 5.11. Listing 5-11
/// <summary>
        /// Add an AD user defined by the login name (DOMAINusername) to a preexisting
SharePoint group.
        /// </summary>
        /// <param name="newUser"></param>
        /// <returns>0 = success, −1 = failure (look in the eventlog for an
exception detail</returns>
        public int AddUserToGroups(User newUser)
        {
            try
            {
                // Get a reference to our SharePoint site (the site URL is defined in the
                // web reference's path. Be sure this is correct).
                UserGroup instance = new UserGroup();
                DefineCredentials(instance);

                // Break apart the comma delimited  groupNames field.
                char[] stringSeparators = new char[] { "|' };
                string[] _SPGroupNames = newUser.groupNames.Split(stringSeparators);

// For each entry in our array of group names, add the user to the specified group.
                foreach (string _GroupName in _SPGroupNames)
                {
                    try
                    {
                        // Invoke the web service via this proxy call.
                        instance.AddUserToGroup(_GroupName,
                            newUser.userName,
                            newUser.userLoginName,
                            newUser.userEmail,
                            newUser.userNotes);
                    }
                    catch (Exception ex)
                    {
                        ErrorLog(ex, newUser);
                        return FAILURE_RESULT;
                    }
                }
                return SUCCESS_RESULT;
            }
            catch (Exception ex)
            {
                ErrorLog(ex, newUser);
                return FAILURE_RESULT;
            }
        }

You've just implemented AddUserToGroups(), so now all that's missing is the inverse function, RemoveUserFromGroups(). This code is pretty similar, but notice that the Remove web service itself requires fewer parameters (see Listing 5-12).

Example 5.12. Listing 5-12
/// <summary>
        /// Remove an AD user defined by the login name (DOMAINusername) from
a preexisting SharePoint group.
        /// </summary>
        /// <param name="newUser"></param>
        /// <returns>0 = success, −1 = failure (look in the eventlog for
an exception detail</returns>
        public int RemoveUserFromGroups(User newUser)
        {
            try
            {
                // Get a reference to our SharePoint site (the site URL is defined in the
                // web reference's path. Be sure this is correct).
                UserGroup instance = new UserGroup();
                DefineCredentials(instance);

                // Break apart the comma delimited groupNames field.
                char[] stringSeparators = new char[] { "|' };

string[] _SPGroupNames = newUser.groupNames.Split(stringSeparators);

                // For each entry in our array of group names, remove the user from
the specified group.
                foreach (string _GroupName in _SPGroupNames)
                {
                    try
                    {
                        // Invoke the web service via this proxy call.
                        instance.RemoveUserFromGroup(_GroupName,
                            newUser.userLoginName);
                    }
                    catch (Exception ex)
                    {
                        ErrorLog(ex, newUser);
                        return FAILURE_RESULT;
                    }
                }
                return SUCCESS_RESULT;
            }
            catch (Exception ex)
            {
                ErrorLog(ex, newUser);
                return FAILURE_RESULT;
            }
        }

This class library will now add and remove users from multiple groups with a single call. Let's build a test harness to try this out. Add a new Console Application project to your solution by clicking File New Project in Visual Studio. Select a new C# Windows Console Application, and name it UserGroupWrapperTestHarness. Add a reference to the Sharepoint.Wrappers.DLL you've just built by right-clicking on the UserGroupWrapperTestHarness project's References folder and select-ing Add Reference. In the Add Reference dialog, select the Projects tab and pick the Sharepoint.Wrappers namespace from the list, as in Figure 5-19.

Figure 5.19. Figure 5-19

Now that the project is ready, rename Class1.cs to TestHarness.cs and put the test code (see Listing 5-13) inside.

Example 5.13. Listing 5-13
using System;
using System.Text;
using Sharepoint.Wrappers;

namespace UserGroupWrapperTestHarness
{
    class TestHarness
    {
        static void Main(string[] args)
        {
            int wsRequestResult = UserGroupWrapper.SUCCESS_RESULT;
            User testUser = new Sharepoint.Wrappers.User();

            testUser = ResetTestUser(testUser);

            UserGroupWrapper AddRemover = new Sharepoint.Wrappers.UserGroupWrapper();

            // Assumptions:  1) The domain is SPTestDomain.
            //               2) User mranlett is a valid Active Directory user.
            //               3) SharePoint groups called "Cool Group" and "Lame Group" have
            //                  already been created.
            Console.WriteLine("Press 1 to add mranlett to the MattTest Group.");
            Console.WriteLine("Press 2 to remove mranlett from the MattTest Group.");
            Console.WriteLine("Press 3 to add mranlett to a nonexistant group.");
            Console.WriteLine("Press 4 to remove mranlett from a nonexistant group.");
            Console.WriteLine("Press 5 to add a nonexistant user to the MattTest Group.");
            Console.WriteLine("Press 6 to remove a nonexistant user from the MattTest Group.");
            Console.WriteLine("Press 7 to call Add with the wrong LoginName.");
            Console.WriteLine("Press 8 to call Remove with the wrong LoginName.");
            Console.WriteLine("Press 9 to call Add with the wrong e-mail address.");
            Console.WriteLine("");
            Console.WriteLine("Press 0 to run the all the test cases at once.");
            Console.WriteLine("Then press ENTER. Any other input is not supported ");
            Console.WriteLine("and may break the test harness.");
            Console.WriteLine("");
            Console.WriteLine("We expect pressing 3, 4, 7, and 8 to generate eventlog errors");
            Console.WriteLine("the other test pass with no errors.");

            int userInput = Console.Read();

switch (userInput)
            {
                case 48: // 48 is hex for 0
                    {
                        // Add a valid user to a valid group.
                        Console.WriteLine("testing the ability to add a valid user to a valid group");
                        wsRequestResult = AddRemover.AddUserToGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("valid user successfully added to a valid group");
                        }
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** error attempting to add a valid user to a valid group. 
 This is unexpected and needs to be researched");
                        }

                        // Remove a valid user from a valid group.
                        Console.WriteLine("testing the ability to remove a valid user from a valid group");
                        wsRequestResult = AddRemover.RemoveUserFromGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("valid user successfully removed from a valid group");
                        }
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** error attempting to add a valid user to a valid group. 
 This is unexpected and needs to be researched");
                        }

                        // Add a valid user to an invalid group.
                        Console.WriteLine("testing the ability to add a valid user to an invalid group");
                        testUser.groupNames = testUser.groupNames + "|BoogaBooga";
                        wsRequestResult = AddRemover.AddUserToGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** added a valid user to an invalid group successfully. 
 This is unexpected and needs to be researched");
                        }
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("error attempting to add a valid user to an invalid group. This is expected");
                        }

// Remove a valid user from an invalid group.
                        testUser = ResetTestUser(testUser);
                        testUser.groupNames = "MattTest||IT Department||Home Owners ||BoogaBooga";
                        wsRequestResult = AddRemover.RemoveUserFromGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** removed a valid user from an invalid group successfully. 
 This is unexpected and needs to be researched");
                        }
                        else
                        {
                            Console.WriteLine("");

                            Console.WriteLine("error attempting to removed a valid user from an invalid group. 
 This is expected");
                        }

                        // Add an invalid user (valid LoginName, invalid userName) to a valid group.
                        testUser = ResetTestUser(testUser);
                        testUser.userName = "ClownNose";
                        wsRequestResult = AddRemover.AddUserToGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("invalid user name with valid user login successfully added to a valid group.
 The user name property is not a validated field.");
                        }
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** error attempting to add an invalid user name with valid user login to a valid group. 
 This is unexpected and needs to be researched");
                        }

                        // Remove an invalid user (valid LoginName, invalid userName) from a valid group.
                        testUser = ResetTestUser(testUser);
                        testUser.userName = "mranlet";
                        wsRequestResult = AddRemover.RemoveUserFromGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("invalid user name with valid user login successfully removed from a valid group.
 The user name property is not a validated field.");
                        }
                        else

{
                            Console.WriteLine("");
                            Console.WriteLine("** error attempting to remove an invalid user name with valid user login from a valid group. 
 This is unexpected and needs to be researched");
                        }

                        // Add an invalid user (invalid LoginName) to a valid group.
                        testUser = ResetTestUser(testUser);
                        testUser.userLoginName = @"FakeDomainBadUID";
                        wsRequestResult = AddRemover.AddUserToGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** invalid user login successfully added to a valid group. 
 This is unexpected and needs to be researched");
                        }
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("error attempting to add an invalid user login to a valid group");
                        }

                        // Remove an invalid user (invalid LoginName) from a valid group.
                        testUser = ResetTestUser(testUser);
                        testUser.userLoginName = @"FakeDomainBadUID";
                        wsRequestResult = AddRemover.RemoveUserFromGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** invalid user login successfully removed from a valid group. 
 This is unexpected and needs to be researched");
                        }
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("error attempting to remove an invalid user login from a valid group");
                        }

                        // Add an invalid user (invalid e-mail address) to a valid group.
                        testUser = ResetTestUser(testUser);
                        testUser.userEmail = "[email protected]";
                        wsRequestResult = AddRemover.AddUserToGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("invalid user e-mail successfully added to a valid group. 
 e-mail is not a validated field.");

}
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** error attempting to add an invalid user e-mail successfully added to a valid group. 
 This is unexpected and needs to be researched");
                        }

                        // Add a user to a group they're already in.
                        testUser = ResetTestUser(testUser);
                        wsRequestResult = AddRemover.AddUserToGroups(testUser);
                        wsRequestResult = AddRemover.AddUserToGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("valid user successfully added to a valid group twice. 
 No problems readding a valid user.");
                        }
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** error attempting to add a valid user to a valid group twice. 
 This is unexpected and needs to be researched");
                        }

                        // Remove a user from a group they're not in.
                        testUser = ResetTestUser(testUser);
                        wsRequestResult = AddRemover.RemoveUserFromGroups(testUser);
                        wsRequestResult = AddRemover.RemoveUserFromGroups(testUser);
                        if (UserGroupWrapper.SUCCESS_RESULT == wsRequestResult)
                        {
                            Console.WriteLine("");
                            Console.WriteLine("valid user successfully removed from a valid group twice. 
 No problem removing non-existant users.");
                        }
                        else
                        {
                            Console.WriteLine("");
                            Console.WriteLine("** error attempting to add a valid user to a valid group. 
 This is unexpected and needs to be researched");
                        }
                        Console.Read();
                        break;
                    }
                case 49: // 49 is hex for 1
                    {
                        // Press 1 to add mranlett to the MattTest Group.
                        AddRemover.AddUserToGroups(testUser);
                        break;
                    }
                case 50: // 50 is hex for 2

{
                        // Press 2 to remove mranlett from the MattTest Group..
                        AddRemover.RemoveUserFromGroups(testUser);
                        break;
                    }
                case 51: // 51 is hex for 3
                    {
                        // Press 3 to add mranlett to a nonexistant group.
                        testUser.groupNames = testUser.groupNames + "|BoogaBooga";
                        AddRemover.AddUserToGroups(testUser);
                        break;
                    }
                case 52: // 52 is hex for 4
                    {
                        // Press 4 to remove mranlett from a nonexistant group.
                        testUser.groupNames = testUser.groupNames + "|BoogaBooga";
                        AddRemover.RemoveUserFromGroups(testUser);
                        break;
                    }
                case 53: // 53 is hex for 5
                    {
                        // Press 5 to add a nonexistant user to the MattTest Group.
                        testUser.userName = "ClownNose";
                        AddRemover.AddUserToGroups(testUser);
                        break;
                    }
                case 54: // 54 is hex for 6
                    {
                        // Press 6 to remove a nonexistant user from the MattTest Group.
                        testUser.userName = "mranlet";
                        AddRemover.RemoveUserFromGroups(testUser);
                        break;
                    }
                case 55: // 55 is hex for 7
                    {
                        // Press 7 to call Add with the wrong LoginName.
                        testUser.userLoginName = @"FakeDomainBadUID";
                        AddRemover.AddUserToGroups(testUser);
                        break;
                    }
                case 56: // 56 is hex for 8
                    {
                        // Press 8 to call Remove with the wrong LoginName.
                        testUser.userLoginName = @"FakeDomainBadUID";
                        AddRemover.RemoveUserFromGroups(testUser);
                        break;
                    }
                case 57: // 57 is hex for 9
                    {
                        // Press 9 to call Add with the wrong e-mail address.
                        testUser.userEmail = "[email protected]";
                        AddRemover.AddUserToGroups(testUser);
                        break;

}
            }
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("End of test cases. Press Enter 2 times to exit");
            Console.Read();
            Console.Read();
            Console.Read();
            Console.Read();

        }

        private static User ResetTestUser(User testUser)
        {
            testUser.groupNames = "Cool Group|Lame Group";
            testUser.userName = "mranlett";
            testUser.userLoginName = @"SPTestDomainmattr";
            testUser.userEmail = "[email protected]";
            testUser.userNotes = "This is a ficticious user added by the web service";
            return testUser;
        }
    }
}

Running this test code will print out your successful and unsuccessful progress. Notice that you have several places where you expect to receive errors. SharePoint relies on Active Directory (in this example) to authenticate users, so your user must already have been created. This example does not actually create new groups, so the groups must preexist. These test cases help illustrate the power and limitations of two simple web services calls.

5.3.1. Deciding between the Object Model and Web Services

Now that you are beginning to appreciate the power and flexibility of the object model and web services, your next decision is to decide between them. Fortunately, there is an easy rule of thumb for deciding between the SharePoint object model and the SharePoint Web Services—where is your code going to be executed? If you're building code that is executed on the SharePoint server, whether in a server application, a service, or a Web Part, use the object model. Directly hooking into the object model is faster and more efficient than using web services. However, web services grant you the flexibility to take your code away from the server. If your requirements include remote applications, even if your servers and workstations are on the same domain, you have to use web services.

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

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