SharePoint Best Practices Coding
|
If you are developer of any specific technology, you should know about best practices of that technology. You may ask why best practices important? Best practices are based on real time experience. so if you are unaware about it, you will end up writing unmaintainable, buggy or unoptimized code.
Lets start discussion about SharePoint best practices with real time example.
- Don't cache SharePoint objects
that are not Thread Safe
Let's take real time
scenario, we have to bind dropdown list with the SharePoint list. We know
SharePoint list which we are binding with dropdown list is not going to change
frequently, so caching will be better option to improve the performance of
theapplication. Sample code is mentioned below:
SPListItemCollection colItems;
if(null != HttpRuntime.Cache[key])
{
ddlItems = (SPListItemCollection)HttpRuntime.Cache[key];
}
else
{
//
Do query on sharepoint listand cach SPListItemCollection object
}
But we are unaware
that SPListItemCollection object contains an
embedded SPWeb object that is not thread safe and should not be cached.
Good Coding Practice
is to cache DataTable in place of SPListItemCollection object.
Sample Code:
private static object _lock = new object();
private DataTable GetDropDownItems()
{
DataTable dtDropDownItems;
SPListItemCollection
objListItems;
lock(_lock)
{
dtDropDownItems= (DataTable)Cache["CachedDropDownItems"];
if(dtDropDownItems== null)
{
objListItems = //Do query onSharePoint List
dtDropDownItems=
objListItems.GetDataTable();
Cache.Add("CachedDropDownItems
", dtDropDownItems,..); //
provide rest of the parameter of this method
}
}
}
Note: There are various methods to cache object like HttpRuntime, System.Web.Caching.Cache,
and HttpContext.Current.Cache. Choose one to the method to cache depending upon
your application requirement.
2. Retrieve or fetch SPList instance from SPWeb object: There might be the multiple approach to get the instance of SPList in SharePoint. But while developing an application we should keep in mind about performance of the application. Mentioned below are two approach to achieve the same.
Approach 1: Not Recommended
SPList objSpList = <SPWeb>.Lists["<List Title>"];
Approach 2: Recommended
SPList objSpList = <SPWeb>.GetList("<List URL>");
In the first approach, SharePoint loads "metadata" of all the SharePoint lists of current SPWeb object and then create SPList instance by Title comparison and also if Title of SharePoint list gets changed, There will be a code change. But in the second approach, SharePoint fetches GUID of the SharePoint list by list url and then loads the "metadata" of that particular list. User can not update the list URL after SharePoint list creation. So there is no possibility of any code change in this approach.
3. JavaScript methods call on page load in SharePoint: Sometime we need to call JavaScript methods on page to change UI or to set some controls value. we can use window.onload event to achieve this functionality. But I personally recommend that to use "_spBodyOnLoadFunctionNames" method provided by SharePoint because sometimes window.onload don't work properly.
Approach 1: Not Recommended
window.onload = funcation(){//JavaScript code};
window.onload = <JavaScript method name>;
Approach 2: Recommended
_spBodyOnLoadFunctionNames.push('<JavaScript method name>');
4. Set RowLimit, ViewFields, and ViewFiledsOnly properties while fetching data from SharePoint list:
Let take me take an example to make understand importance of these properties.
Scenario: Suppose there isa list
to store employee details. Following fields are present in this list:
· Name
· Designation
· Domain
· Address
· Email
· Contact Number
· Rating
We have to create a webpart to show top 5 employees name,
designation and email in the home
page of site based on employee
rating.
To achieve above mention scenario, we will end up with mentioned below code sample:
To achieve above mention scenario, we will end up with mentioned below code sample:
Bad coding:
using (SPSite objSite = new SPSite("<Site
URL>"))
{
using (SPWeb objWeb =
objSite.OpenWeb())
{
SPList objList =
objWeb.GetList("<List
URL>");
SPQuery objQuery
= new SPQuery();
objQuery.Query = @"<OrderBy>
<FieldRef Name='ID' Ascending='False' />
</OrderBy>";
SPListItemCollection employeeCollection
= objList.GetItems(objQuery);
}
}
|
In
the above mentioned codeblock, we will fetch all the fields data but we have to
display only 3 fieldsdata in the webpart. So there will be performance hit. As
a good practice weshould pass ViewFields also. so that our query will return
required fields data only.
Add following line of code to improve the performation:
Good coding
Add following line of code to improve the performation:
Good coding
//We have specified view fields, now our query will fetch
value of these three fields data.
objQuery.ViewFields
= @"<FieldRef Name='Name'/>
<FieldRef
Name='Designation'/>
<FieldRef
Name='Email'/>";
|
Even though we have specified view fields, still SharePoint fetches following fields data:
· ID
· Created
· Modified
As
per problem statement, we do not want these fields data. SPQuery object has
property called ViewFieldsOnly. If we set this property to true, these fields
data will not come with the query result. It means, to improve our query
performance, we will have to add one more line in our code:
Good coding:
objQuery.ViewFieldsOnly = true; |
Note: If you have to do write
operation on fetched records by our query, do not set ViewFieldsOnly property
to true otherwise while updating any
item you will get following exception: "Value does not fall within the
expected range."
Still we can improve our code. Here we need to show only 5 employees details and our query will fetch all employee details. So we can improve our code by providing RowLimit to 5.
Still we can improve our code. Here we need to show only 5 employees details and our query will fetch all employee details. So we can improve our code by providing RowLimit to 5.
Good coding:
objQuery.RowLimit = 5; |
Note: Most of the time we do not know how many records will fetch after query execution. But as best practice we should set RowLimit if we know the threshold of our query.
Now we know, when to set which property and why these properties are important.
https://sureshunakka87.wordpress.com/2014/05/03/best-practices-using-disposable-windows-sharepoint-services-objects/
Best Practices: Using Disposable Windows SharePoint
Services Objects
SPWeb.Lists
Vs SPWeb.GetList
There
are many posts on this topic. So why I am writing one more post? Well just to
share my experience and hope others will benefit from this.
SPWeb.GetList (string strUrl) –
Good
using (SPSite site = new SPSite(strSite))
{
using (SPWeb web = site.OpenWeb())
{
SPList oList = web.GetList(http://Site/list/AllItem.aspx)
}
}
using (SPSite site = new SPSite(strSite))
{
using (SPWeb web = site.OpenWeb())
{
SPList oList = web.GetList(http://Site/list/AllItem.aspx)
}
}
In this case, first retrieves the list GUID from the url
(database hit), then it loads the metadata* for that specific list.
SPWeb.Lists (“name”) – Not Good
using (SPSite site = new SPSite(strSite))
{
using (SPWeb web = site.OpenWeb())
{
SPList oList = web.Lists [“MyList”]
}
}
using (SPSite site = new SPSite(strSite))
{
using (SPWeb web = site.OpenWeb())
{
SPList oList = web.Lists [“MyList”]
}
}
Please
reffer the url for more Disposing
sharepoint objects .
Cheers!!!!
No comments:
Post a Comment