Showing posts with label MOSS 2007 Object Model. Show all posts
Showing posts with label MOSS 2007 Object Model. Show all posts

Monday, March 15, 2010

Best Coding Practices For Using Sharepoint Object Model

Content:
  • Introduction
  • Using objects in event receivers
  • Disabling Event Firing
  • Working with folders and lists
  • Using SPQuey Objects
  • Dispose WSS Objects
  • Subfolder creation in a list 
Introduction:
WSS provides a highly structured server-side object model that makes it easy to access objects that represents the various aspects of a SharePoint Web site. From higher-level objects, we can drill down through the object hierarchy to obtain the required object to be used in our code.
Diagram depicting the WSS site architecture in relation to the collections and objects of the Microsoft. SharePoint namespace is as follows:

While creating a new application or to improve the performance, extensibility and scalability of existing application it is important to understand how to make the SharePoint object model work efficiently, and how to apply general programming techniques to the SharePoint platform specifically. These common best coding practices can make it easier to design our applications correctly, find and fix problem areas in our code, and avoid known pitfalls of using the SharePoint object model.

Using Objects in Event Receivers:

SPWeb, SPSite, SPList, or SPListItem objects should not be instantiated within an event receiver. Within Event Receivers instead of using these objects event properties should be used otherwise following problems may occur:

• They incur significant additional roundtrips to the database. (One write operation can result in up to five additional roundtrips in each event receiver.)

• Calling the Update method on these instances can cause subsequent Update calls in other registered event receivers to fail.

Disabling Event firing:
Event handlers are fired synchronously or asynchronously for every addition, update, and deletion etc. if also that is not required from different code execution and it can cause performance degradation and unnecessary execution of event handlers code. So these event handlers must be disabled whenever not required. Code for this is:

public static void EnableEventFiring()
{
SetEventFiringSwitch(false);
}
public static void DisableEventFiring()
{
SetEventFiringSwitch(true);
}
private static void SetEventFiringSwitch(bool value)
{
PropertyInfo pi = EventManagerType.GetProperty(_eventFiringSwitchName, System.Reflection.BindingFlags.Static
System.Reflection.BindingFlags.NonPublic);
pi.SetValue(null, value, null);
}
private static bool GetEventFiringSwitchValue()
{
PropertyInfo pi = EventManagerType.GetProperty(_eventFiringSwitchName, System.Reflection.BindingFlags.Static
System.Reflection.BindingFlags.NonPublic);
object val = pi.GetValue(null, null);
return (bool)val;
}
private static Type GetEventManagerType()
{
_eventManagerType = typeof(SPList).Assembly.GetType(_className, true);
return _eventManagerType;
}
Working with folders and lists:
Working with large lists and folders needs conventional design change to optimize performance which is as follows:

  • Instead of using SPList.Items use SPList.GetItems(SPQuery query) and apply appropriate filter on query to make it more efficient. If list contains more than 2000 items then paginate the list in increments of no more than 2000 items.
  • Instead of using SPList.Items.GetItemById use SPList.GetItemById.
  • While adding a new item in a list instead of using SPList.Items.Add use SPList.GetItems(q).Add where q is empty query. Code for this is:- const
string EmptyQuery = "0";
SPQuery q = new SPQuery { Query = EmptyQuery };
SPListItem item = List.GetItems(q).Add();
  • Do not enumerate entire SPList.Items collections or SPFolder.Files collections.
  • While retrieving SPList object instead of getting it by using list’s name use its GUID or URL of the list.
Using SPQuery Objects:
When SPQuery returns large result sets than that can cause performance problem so points to keep in mind while designing query are as follows:
  • Use RowLimit between 1 and 2000 for SPQuery and paginate through the list if required.
  • If List Item URL is known than query list by using FileRef like SPWeb.GetListItem(string strUrl, string field1, params string[] fields).
  • Whenever possible use indexed columns in where clause of SPQuery.

Dispose WSS Objects:
WSS object model contains objects that implement the IDisposable interface. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. It is not known that when garbage collector will execute. Furthermore, the garbage collector has no knowledge of unmanaged resources. So Dispose method of this interface should be explicitly called to release unmanaged resources in conjunction with the garbage collector.

SPSite and SPWeb objects are managed objects but use unmanaged code and memory to do majority of their work. The managed part of the object is much smaller than the unmanaged part. Because the smaller managed part does not put memory pressure on the garbage collector, the garbage collector does not release the object from memory in a timely manner. The object's use of a large amount of unmanaged memory can cause some of the unusual behaviors like poor performance, application crash, high memory use of IIS worker process. Calling applications that work with IDisposable objects in Windows SharePoint Services must dispose of the objects when the applications finish using them. We should not rely on the garbage collector to release them from memory automatically.
We can employ certain coding techniques to ensure object disposal. These techniques include using the following in our code:
  • Dispose method
  • using clause
  • try, catch, and finally blocks
Subfolder Creation in a list:
If list size exceeds 2000 items then Microsoft recommends having subfolders for every 2000 items in a list. Then use SPQuery.ViewAttributes = "Scope=\"Recursive\"" for querying data through SPQuery and if possible than query only from subfolder by giving its name.

Monday, January 28, 2008

Creating Sites and List folders in a SharePoint using C# programmatically

Purpose of the Content:
Objective of this document is to throw some light on object model in MOSS using C#
This article will cover following topics
1. Introduction
2. Prerequisites
3. SPWebCollection.Add Method
4. Creating sites in SharePoint
5.SPListItemCollection.Add Method:
6.Creating folders in SharePoint List:


Introduction
The Windows SharePoint Services object model consists of forty-two namespaces in ten assemblies that are used in SharePoint sites on the server that is running Windows SharePoint Services1. The Microsoft.SharePoint and Microsoft.SharePoint.Administration namespaces provide types and members that can be used with lists and sites, as well as to manage a server or collection of servers that are running Windows SharePoint Services.

Now creating sites programmatically is one of the features that SharePoint SDK provides. The following sections will focus on how we can achieve this functionality.



Prerequisites :
Creating sites may be one of the task or the only that a web part does। So one must know how to develop and configure the web parts using SharePoint. Here I m using a web part consist a button on click of which, the new site creation logic will execute.

While sites are created through SharePoint we associate a site template name with the site. So it will be helpful to know how to develop and configure custom site templates if you want to use in new site. You can also refer the existing site template provided by SharePoint

SPWebCollection.Add Method:
The method Creates a Web site object with the specified site-relative URL, title, description, locale ID, and site definition or site template object.

SPWebCollection.Add Method (String, String, String, UInt32, SPWebTemplate, Boolean, Boolean) (Microsoft.SharePoint)

Namespace: Microsoft.SharePointAssembly: Microsoft.SharePoint (in microsoft.sharepoint.dll)
public SPWeb Add (
string strWebUrl,
string strTitle,
string strDescription,
uint nLCID,
SPWebTemplate WebTemplate,
bool useUniquePermissions,
bool bConvertIfThere
)

Parameters:


1· strWebUrl :A string that contains the new Web site URL relative to the root Web site in the site collection. For example, to create a Web site at http://MyServer/sites/MySiteCollection/MyNewWebsite, specify MyNewWebsite, or to create a Web site one level lower at http://MyServer/sites/MySiteCollection/Website/MyNewWebsite, specify Website/MyNewWebsite.

2· strTitle: A string that contains the title.

3· strDescription: A string that contains the description.

4· nLCID: An unsigned 32-bit integer that specifies the locale ID.

5· WebTemplate: An
SPWebTemplate object that represents the site definition or site template.

6· useUniquePermissions: true to create a subsite that does not inherit permissions from another site; otherwise, false.

7· bConvertIfThere: true to convert an existing folder of the same name to a SharePoint site. false to throw an exception that indicates that a URL path with the specified site name already exists.


Return ValueAn SPWeb object that represents the Web site.

Creating sites in SharePoint:

1· Add the following namespaces and reference the DLL Microsoft. SharePoint.dll
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

2· Get the sp web object of the current site in which site is to create as
SPWeb spCurrentWeb = new SPSite(strSiteURL).OpenWeb(); where strSiteURL is the URL of the site as http://chdsez108269d:999/

3· Place the site template in the following SharePoint directory
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\

4· Now call the following function with given required parameters
private SPWeb CreateNewSite(SPWeb spCurrentWeb, string siteName, string siteDesc, string siteTemplateName, string strWebUrl)

Usage:

SPWeb spEventWeb = this.CreateNewSite(spcurrentweb, ”MyNewSite”,”siteDescription”,”MyCustomTemplate”,”MyNewSiteURL”))

Where spcurrentweb is spweb object of current site
o siteName and siteDesc is the name and description of the new site to create
o siteTemplateName is name of the template of the new site
o strWebUrl is the relative URL of the new site which can be different or same as the siteName
Full function body is below

private SPWeb CreateNewSite(SPWeb spCurrentWeb, string siteName, string siteDesc, string siteTemplateName, string strWebUrl)
{
try
{
if (spCurrentWeb != null)
{
if (spCurrentWeb.Webs[siteName].Exists == false)
{
//get the template collection from site based on locale Id
SPWebTemplateCollection Templates = spCurrentWeb.Site.GetWebTemplates(Convert.ToUInt32(1033));
if (Templates != null)
{
//get the template object from template collection based on locale Id
SPWebTemplate siteTemplate = Templates[siteTemplateName];
if (siteTemplate != null)
{
//create a new site and add it in web collection of the parent web
using (SPWeb spChildWeb = spCurrentWeb.Webs.Add(strWebUrl, siteName, siteDesc, (uint)1033, siteTemplate, false, false))
{
if (spChildWeb != null)
{
spChildWeb.AllowUnsafeUpdates = true;
spChildWeb.Update();
return spChildWeb;
}
else
{
throw new Exception("Site " + siteName + "can't be created");
}
}
}
}
}
else
{
throw new Exception("Site " + siteName + " already exist");
}
}
return null;
}
catch (Exception ex)
{
LogException(ex, "Site can't be created!!! some exception has occoured");
return null;
}
finally
{
if (spCurrentWeb != null)
spCurrentWeb.Dispose();
}
}

SPListItemCollection.Add Method:

The following method Create an item that uses the specified folder URL, object type, and leaf name but requires the Update method to actually add the item to the list.

SPListItemCollection.Add Method (String, SPFileSystemObjectType, String) (Microsoft.SharePoint)

Namespace: Microsoft.SharePointAssembly: Microsoft.SharePoint (in microsoft.sharepoint.dll)

public SPListItem Add
(
string folderUrl,
SPFileSystemObjectType underlyingObjectType,
string leafName
)
Parameters

o folderUrl : A string that contains the server-relative URL of the folder, beginning with a forward slash; for example, /sites/mysite/subweb/Lists/mylist/myfolder.

underlyingObjectType : A
Microsoft.SharePoint.SPFileSystemObjectType value that indicates the object type. Only File and Folder are valid types for the underlying object type.


leafName: A string that contains the leaf name, which is everything after the last forward slash in the URL, including the file extension.

Return Value: A
Microsoft.SharePoint.SPListItem object that represents the new item.
Creating folders in SharePoint List:
1· Add the following namespaces and reference the DLL Microsoft. SharePoint.dll
using Microsoft.SharePoint;

2· Get the sp web object of the current site in which site is to create as
SPWeb spCurrentWeb = new SPSite(strSiteURL).OpenWeb(); where strSiteURL is the URL of the site as http://chdsez108269d:999/

3· Now call the following function with given required parameters


private SPFolder GetFolder(SPWeb spCurrentWeb,string strSiteLink, string strListName, string strFolderName)
Usage:

spFolder spNewFolder = this.GetFolder(spcurrentweb, “MySiteLink”, “MyListName”, “MyFolderName”);
Where spcurrentweb is spweb object of current site
o MyListName and MyFolderName is the list name and folder name in the given list.
o MySiteLink is the relative URL of the new site which can be different or same as the siteName
Full function body is below


private SPFolder GetFolder(SPWeb spCurrentWeb,string strSiteLink, string strListName, string strFolderName)
{
using (spCurrentWeb)
{
if (!string.IsNullOrEmpty(strFolderName))
{
//create a folder with the given name in the event list if don't exist, otherwise return the existing folder
if (spCurrentWeb.GetFolder("Lists/" + strListName + "/" + strFolderName).Exists != true)
{
spCurrentWeb.AllowUnsafeUpdates = true;
SPList spListEvent = spCurrentWeb.Lists[strListName];
//create a new folder in the list
SPListItem spFolderEvent = spListEvent.Items.Add(strSiteLink + "/Lists/" + strListName, SPFileSystemObjectType.Folder, strFolderName);
spFolderEvent.Update();
spListEvent.Update();
spCurrentWeb.Update();
}
//return the existing folder from the list
return spCurrentWeb.GetFolder("Lists/" + strListName + "/" + strFolderName);
}
return null;
}
}




References:
http://msdn2.microsoft.com/en-us/library/ms439689.aspx
http://msdn2.microsoft.com/en-us/library/ms448720.aspx