SharePoint 2010 Best Practices
While developing custom solutions based on SharePoint, we need to strictly adhere certain best practices that are proposed by Microsoft SharePoint team.
1.1 Usage of SharePoint Object Model
Most of the SharePoint developers use SharePoint API’s like SPSite, SPWeb, SPList objects extensively. There will be a serious performance hits and memory leaks, when those objects are not properly used.
In most of the cases the code will work well, but whenever the data get heavy, there should be a huge performance hits, because of not properly usage of SharePoint API’s.
This section will elaborate about the best practices on how to use SharePoint API’s especially when we use objects like SPSite, SPWeb, SPList, etc., and also some coding practices.
A good or best practice we need to follow is whenever we use SPSite, SPWeb objects, we need to properly dispose those objects; otherwise, there will be a huge performance impact.
public void SPSiteAndSPWebProperlyDisposeUsing () { using (SPSite site = new SPSite(http://moss)) { using (SPWeb web = site.OpenWeb ()) { //do your logic } } } |
One thing we need to remember that, we when we create an instance of SPSite or SPWeb using SPControl or SPContext class, do not dispose the instance of SPSite or SPWeb objects.
For example
SPSite site = SPControl.GetContextSite (Context); site.Dispose (); //Do not do this SPWeb web = SPControl.GetContextWeb (Context); web.Dispose (); //Do not do this SPSite site = SPContext.Current.Site; site.Dispose (); //do not do this SPWeb web = SPContext.Current.Web; web.Dispose (); //do not do this |
Note: We do not need to dispose the SPWeb instance when using SPSite.RootWeb and SPSite.ParentWeb properties
There is a tool called “SPDisposeCheck”, which will guide us to check whether all the SPSite and SPWeb instances are properly disposed. This tool will check the assembly and reports the developer how many instances are not disposed properly. Also we can add this utility in our Visual Studio environment.
There are several other SharePoint objects that are required to be disposed properly. For more details refer to the reference section links.
1.2 Interacting with large SharePoint list using SharePoint object model
When we interacting with list containing huge number of items using SharePoint OM, we may need to consider the following best practices
Case # 1: Getting the list items count
Using SharePoint OM, we can get the list item count like
int count = SPContext.Current.List.Items.count; //Do not use |
The above code snippet is valid to get the count, if the list is tiny. At the same time, if the list contains huge items, there will be a performance degrade with above code. Since List.Items.Count retrieve all the list items in the memory and find out the total count.
In order to avoid this, we can use the following code to retrieve the total items count even though the list contains huge items
int count = SPContext.Current.List.ItemCount; //Use this code |
Here, the ItemCount is the metadata of a list and will be created whenever we create a new instance of a list.
Case # 2: Iterating the list items to display
We can iterate through the list items using SharePoint OM as follows:
SPList list = SPContext.Current.List; for(int i=0; i { SPListItem item = list.Items[i]; htmlWriter.Write(item[“Title”]); } |
The above code snippet is incorrect way to access the list items, because for each loop, there is a new instance of SPListItemCollection gets created when accessing Items property. Also, the Items property will not be cached and therefore request the database for each loop.
The correct way to do it:
SPListItemCollection itemsCol = SPContext.Current.List.Items; for(int i=0; i { SPListItem item = itemsCol[i]; htmlWriter.Write(item[“Title”]); } |
Case # 3: Retrieve required items we need - SPQuery and SPView SharePoint OM
Instead of retrieving all the items from the list, we can retrieve only the required items from list.
For this purpose, we can use SPQuery and SPView objects
Limiting the number of returned rows:-
Using SPQuery instance, we can limit the number of rows to be retrieved from the list, so as to avoid all the items from the list.
SPQuery query = new SPQuery(); query.RowLimit = 100; //Here, we are limiting the items to be returned only 100 |
Limiting the number the columns to be retrieved:-
Let’s say, a SharePoint list contains 100 columns, and it is not a good practice to retrieve columns that are not necessary. For this, we have two approaches to limit the retrieved columns
Using SPView instance:-
SPQuery query = new SPQuery (SPContext.Current.CurrentView.View); |
Using SPQuery.ViewFields property:-
SPQuery query = new SPQuery (); Query.ViewFields = “ |
In both cases, the select statement will have only the required columns.
Case # 4: Retrieving list items using PortalSiteMapProvider
The PortalSiteMapProvider is one of the ways to retrieve list items from SharePoint very efficiently. It is a MOSS feature and provides an automatic caching mechanism to cache the list items.
PortalSiteMapProvider class has a method namely GetCachedListItemsByQuery takes the instance of SPQuery as parameter for retrieving the list items.
Prior to retrieving the list items, it checks whether the list items is available in cache, if so it retrieves from cache, otherwise, it retrieves from database and put it in cache for next retrieval.
The advantage of this method is it doesn’t have to retrieve the list items from database every time and hence improve the performance.
There are some limitations of using this method as well
· Do not use this method to retrieve the list items, which are not static data, because it continually checks for cache, if not retrieves the items from database and again put it in cache. There are some performance degrade in terms of checking and writing back to cache
· Default memory size for the cache is 100 MB, but we can increase the size. The increased size has to be taken from the shared memory of the application pool and there by affect the performance of the other applications
· We cannot use the PortalSiteMapProvider class in applications like Windows Forms
Following shows the code snippet on how to use the PortalSiteMapProvider efficiently
SPWeb web = SPControl.GetContextWeb (HttpContext.Current); SPQuery query = new SPQuery (); query.Query = " PortalSiteMapProvider portal = PortalSiteMapProvider.WebSiteMapProvider; PortalWebSiteMapNode portalNode = portal.FindSiteMapNode (web.ServerRelativeUrl) as PortalWebSiteMapNode; SiteMapNodeCollection portalItems = portal.GetCachedListItemsByQuery (pNode, "myListName_NotID", query, web); foreach (PortalListItemSiteMapNode item in portalItems) { // Do something with each match. } |
1.3 Caching Objects for better Performance
Caching is one of the techniques in .NET world to increase the performance by reducing the roundtrips to backend database. In SharePoint also, we can leverage the .NET class (System.Web.Caching.Cache) to cache the SharePoint objects.
Caching helps us to reduce the usage of memory and increase the overall system performance. But, many objects are not “thread safe” and caching those objects can lead to application crashes and unexpected or unrelated use errors.
There are few considerations we need to take care when caching SharePoint objects.
Caching SharePoint objects that are not thread safe:
When we trying to get list items from a SharePoint list using SPQuery object and results are stored in SPListItemCollections objects, it is a good practice to cache the SPListItemCollections object.
But, the object SPListItemCollections will contain an embedded SPWeb object, which is not thread safe and should not be cached. When it is cached, there might be some unexpected errors.
So, don’t cache the objects which are thread unsafe.
Not using Thread Synchronization:
We need to know understand that the IIS is a multi-thread environment and many users can access the site simultaneously. We need to write code that target for multi-thread environment
public void CacheItems () { SPListItemCollections listItems; listItems = (SPListItemCollections) Cache [“ListItemsData”]; if (listItems == null) { listItems = getData (); Cache.Add (“ListItemsData”, listItems); } } |
In the above code snippet, the problem is that if the query to get items takes 10 seconds, there might be a chance that many users can hit the page simultaneously, trying to get the items and update the cache objects at the same time.
Since the same query might run 10, 50 or 100 times, there should be a performance issues and worst case the application may crash because multiple threads are trying to update the same cache objects.
To avoid this scenario, we need to modify the above code snippet as shown below
public void CacheItems () { SPListItemCollections listItems; lock (this) { listItems = (SPListItemCollections) Cache [“ListItemsData”]; if (listItems == null) { listItems = getData (); Cache.Add (“ListItemsData”, listItems); } } } |
In the above sample code snippet, lock (this) statement ensures that when a thread is inside lock statement and another thread attempts to enter, it place a lock over that thread until the previous thread leaves the lock statement.
Caching an object which is thread safe:
Always cache the objects, which are “thread safe”. In the above code, SPListItemCollections is not a thread safe object, since SPWeb object is embedded in it, which is thread unsafe.
In order to cache the SPListItemCollections in order to avoid roundtrips to backend database, use DataTable .NET object to cache instead of SPListItemCollections as shown below
public void CacheItems () { DataTable dtItems; SPListItemCollections listItems; lock (this) { dtItems = (DataTable) Cache [“ListItemsData”]; if (dtItems == null) { listItems = getData (); dtItems = listItems.GetDataTable (); Cache.Add (“ListItemsData”, dtItems); } } } |
1.4 SharePoint naming conventions
1.4.1 URL length
A limitation of SharePoint to be reckoned with is the fact that the total length of a URL in SharePoint may no longer than 260 characters.
It is therefore necessary to keep URL names of sites, libraries and to a lesser extent also lists, as short as possible without the clarity and definition deficit is made.
Clear guidelines help here, so see below for an explanation of naming components of Microsoft Office SharePoint Server 2007.
These guidelines should be known to all those potential sites, libraries and / or lists in Microsoft Office SharePoint Server 2007.
1.4.2 Features
Features need to be uniquely named.
1.4.3 Naming of Items in SharePoint
Lists & libraries
Provide lists and libraries with a short but full name clearly describing the application.
Keep the following guidelines:
· Use plural nouns, optionally combined with an adjective
· Avoid using punctuation in their name
· Do not take the name of the site in the list or library name
· Take only words like Documents, Library List, or when it adds value
· Start each word is capitalized
Templates
Templates Give a short name that describes its full content or function.
This, keep the following guidelines:
· For the filename (filename) exactly the same name but without spaces
· Use singular nouns in
· Avoid using punctuation in their name
· Start each word is capitalized
· Take the name for clarity on the template type (eg Project Site, Project Page, Project or Project Library List)
Good names include:
· Project Library (filename ProjectBibliotheek.stp)
· Timesheet List (filename UrenverantwoordingLijst.stp)
· SharePoint Training Site (filename SharePointTraining.stp)
For example:
Title: Standard | Name: Standaard.master | Description: The default master page with corporate branding |
Title: Regional | Name: Regionaal.master | Description: A derivative of the standard master page with regional branding |
Title: News Overview | Name: NieuwsOverzicht.aspx | Description: A list of news articles collected from current and underlying sites, webparts area on the right |
Title: News Article | Name: NieuwsArtikel.aspx | Description: Standard pre-defined layout for news |
Webparts
Give Web a full name that the functionality of the Web completely and unambiguously describes.
This, keep the following guidelines:
· Start each word is capitalized
· Use Pascal case for the file name
· Keep file names as identical as possible to the title, but without spaces and punctuation
Web Applications
Web Applications Provide a name that fully describes the content or function.
This, keep the following guidelines:
· Use the name of the application
· Avoid using punctuation in their name
· Start each word is capitalized
Good names include:
· Intranet Publication
· Partner Portal
· My Sites
Site Collections
Site Collections Give a name that completely describes its content or function.
This, keep the following guidelines:
· The name provides a grouping of the underlying sites
· Avoid using punctuation in their name
· Start each word is capitalized
· Observe the alphabetical sorting of Site Collection inside a web application
Good names include:
· Intranet GB
· Arnhem
· Public Blogs
Sites
Sites Enter a name that fully describes its content or function.
This, keep the following guidelines:
· The name indicates a specific application or part of the Site Collection to
· Avoid using punctuation in their name
· Start each word is capitalized
· Observe the alphabetical sorting of Sites within a Site Collection and menus and such.
Good names include:
· Search
· News
· Personnel Department
· Strategy
· Steve's Blog
Pages
Give titles and contents pages try to file as much as possible to match with the
title.
· This, keep the following guidelines:
· The more keywords in the title the better the result will be
· Avoid using punctuation in their name
Good names include:
· Abstract Social Report
filename: AbstractSociaalJaarverslag.aspx
· Overview of contact regional offices
Filename: Overzichtvancontactgegevensregiokantoren.aspx
Site Columns
Enter a descriptive name that does not overlap in meaning with other columns.
When used for a specific application and / or for a specific type of content, use for grouping of the columns the name of the application and / or content type.
When creating the column is important to the column name in Pascal case with no spaces or punctuation to fill. This cannot be adjusted later.
After creating the column, the column can be adjusted and the correct name to be filled, starting each word with a capital letter.
Good names include:
· Project Status
· Internal name: project status
· Internal Product Registration Code
· Internal name: internal product registration code
Content types
Give a descriptive name given to a logical grouping of Site
Columns usually describes a specific application. When specific to the Content Type, columns are prepared they will be grouped under exactly the same as the name of the Content Type.
This, keep the following guidelines:
· The name indicates a group of Site Columns
· Avoid using punctuation in their name
· Start each word is capitalized
· Observe the alphabetical sorting of Site Collection inside
Good names include:
· Incoming Invoice
· PID
1.4.4 Naming of Content
Titles
Page titles for a number of reasons one of the main components of a web page.
Make sure the title is a substantive description of the page where the most meaningful keywords to find the page are included.
The title is used for indexing and ranking of the page to search the contents of the title usually weighs more heavily than other information on the page.
Also, the title used in the display of search, navigation and other dynamic lists. It is therefore important to be aware that even if the title appears in a different context (eg in a block of related pages) should be more fully descriptive.
Example: Procedure Calling in sick: What to do when you are sick
Hyperlinks
When placing hyperlinks in text, it is important to ensure that the hyperlink itself as fully as possible the contents of the destination page describes.
Do not take "Click here" or "Read More" links but make sure the hyperlink itself describes the target content. Indexing for search as well as mobile browsers make good use of descriptive links.
If the hyperlink text is not like an image or a block of information, it can still define the TITLE attribute of the hyperlink itself can be added.
Navigation block
When placing hyperlinks in navigation blocks, it is important to ensure that the hyperlink itself as fully as possible the contents of the destination page describes in the fewest words.
Please also do not list "Click" on hyperlinks, and no navigation icons.
Nevertheless if necessary to make sure that the TITLE attribute for navigation provides a good description of the hyperlink.
Labeling of elements
It is recommended by a LABEL (FOR attribute) to refer to form element so that
users can use this interface and the machine also "understands" that the label describes the control.
Dictionary: Imagine an application and possibly also a comprehensive dictionary of universal terms and names as they appear in the various applications used to universal terms and names as they appear in the various applications used to be.
2 Deployment
2.1 Versioning
2.2 WSP / Feature structure
2.2.1 General
Group multiple artifacts in one feature.
Note that features are visible in site settings so we do not need a list of 30 ENDK features
Group by functionally (so not technically by artifact)
This way updates can be by functional area, developer is responsible for package.
Ofcourse there have to be ‘general’ packages, grouped by artefact as well
(e.g. master page and visual design)
-but we do not want 40 wsp’s with one feature.
2.2.2 WSP
Separate code from content definitions.
Reason – this allows code to be updated without affecting content (types) definitons
No Farm scoped WSP’s
Since these apply to All web applications on the farm
2.2.3 Feature
No hidden features
Since these are hard to find later and are poorly manageable .
Use feature and solution dependencies.
Make WSP’s dependent on other Wsp’s where needed (note this only applies on first installation, not on uninstall or update!)
No web application scoped featurus - scope features appropriately
Note scope. Site scoped features cannot be dependent on site Collection features
3 Decisions
3.1 GAC of bin
We deploy or code in the GAC.
Reason
· Simplification
· Some code has to be in GAC anyway (workflow, timer job, masterpage).
· No issues with trust level and CAS policy
· No record of injection of security breaches (by having a component in the GAC executing web-injected code exists)
3.2 webparts development in codebehind of via loading usercontrols
We wrap usercontrols in webparts (using visual webpart)
Reason
· Developer productivity (using design view in VS)
· Functionality same as code only webparts
· Ascx has to be deployed separately in SP2007. 2010 uses visual webparts so – no issue there.
3.3 content types via CAML of from code
3.4 site definitions
Refrain from using site definitions!
These are non updateable when content exists. Use features.
4 References
4.1 Dispose patterns of SharePoint APIs
http://msdn.microsoft.com/en-us/library/bb687949.aspx
http://msdn.microsoft.com/en-us/library/aa973248.aspx
http://blogs.technet.com/stefan_gossner/archive/2008/12/05/disposing-spweb-and-spsite-objects.aspx
http://blogs.msdn.com/rogerla/archive/2008/10/04/updated-spsite-rootweb-dispose-guidance.aspx
No comments:
Post a Comment
Thank you for Commenting Will reply soon ......