Friday, February 17, 2012

Attempted to use an object that has ceased to exist. (Exception from HRESULT: 0×80030102 (STG_E_REVERTED))

Resolved Attempted to use an object that has ceased to exist. (Exception from HRESULT: 0×80030102 (STG_E_REVERTED))



When working with visual webpart control, my visual webpart works fine, but when i deploy the more then one Visual webpart on a single page, it gives me above error, while going in to many forums and reading the blogs, i was wondering there is some thing with my code and the SPSite and SPWeb object disposal.
i used to write the code like this
using (SPSite site =SPContext.Current.Site)
{
using (SPWeb web = site.OpenWeb())
{
// your code
}
}
though i am scoping the object rightly(using automatically dispose the object the routine gets outside the scope), but there is still some thing missing, after some time i figured out that the problem is with SPContext object rather than SPsite object, because once it dispose in one Visual Webpart, it can not be acquired back, so i change the code like this
using (SPSite site = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb web = site.OpenWeb())
{
// your code
}
}
and do use the using scope, it will save you from explicitly disposing the objects

Best Practices disposing Sharepoint objects - Reference Guide


Best Practices disposing Sharepoint objects - Reference Guide

Frequently developers use the Sharepoint object model either to read or write data into Share point database via Lists/Libraries. Here comes the need to dispose Sharepoint objects, even though they are created as managed objects, these objects use unmanaged code and memory to perform a majority of their work.

Because the smaller managed part of the object 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 described as follows:
  • Frequent recycles of the Microsoft Windows SharePoint Services application pool, especially during peak usage
  • Application crashes that appear as heap corruption in the debugger
  • High memory use for Microsoft Internet Information Services (IIS) worker processes
  • Poor system and application performance
Applications that work with IDisposable objects in MOSS must dispose of the objects when the applications finish using them. You should not rely on the garbage collector to release them from memory automatically.

Unusual behaviors mentioned above occur when Sharepoint objects are not disposed off properly or explicitly by the devlopers. Here is a reference guide on Sharepoint Coding best practices with relevant scenarios and examples of each type:

Three techniques to ensure that your objects get disposed properly:

  • Dispose method
  • using clause
  • trycatch, and finally blocks
Whenever you wish to free memory resources, call Dispose method, instead of the Close method , internally Dispose method calls Close methoditself, the reason being that standard .NET Framework process calls the Dispose method to free memory resources associated with object.

Thankfully Microsoft has recently launched Sharepoint Dispose Checker utility. It will ensure that you have properly disposed objects so that you aren't consuming more memory. All developers should run this utility after they use Sharepoint object model. Click here to download SPDispose Utility.

NOTE : This post is applicable for both SharePoint 2010 and SharePoint 2007

Best Practice #1: Use the Using Clause for all Sharepoint objects that implement the IDisposable interface
C# Coding snippet

String str;

using(SPSite oSPsite = new SPSite("http://server"))
{
using(SPWeb oSPWeb = oSPSite.OpenWeb())
{
str = oSPWeb.Title;
str = oSPWeb.Url;
}
}

Best Practice #2: Use the try/catch/finally blocks. When you use try blocks, it is important to add a finally block to ensure that all objects are disposed off properly:

C# Coding snippet

String str;
SPSite oSPSite = null;
SPWeb oSPWeb = null;

try
{
oSPSite = new SPSite("http://server");
oSPWeb = oSPSite.OpenWeb(..);

str = oSPWeb.Title;
}
catch(Exception e)
{
}
finally
{
if (oSPWeb != null)
oSPWeb.Dispose();

if (oSPSite != null)
oSPSite.Dispose();
}

Best Practice #3: Using Response.Redirect in the try block will never execute the finally block, so it is important, to dispose off all objects before the redirection occurs:

C# Coding snippet
String str;
SPSite oSPSite = null;
SPWeb oSPWeb = null;
bool bDoRedirection = true;

try
{
oSPSite = new SPSite("http://server");
oSPWeb = oSPSite.OpenWeb(..);

str = oSPWeb.Title;
if(bDoRedirection)
{
if (oSPWeb != null)
oSPWeb.Dispose();

if (oSPSite != null)
oSPSite.Dispose();

Response.Redirect("newpage.aspx");
}
}
catch(Exception e)
{
}
finally
{
if (oSPWeb != null)
oSPWeb.Dispose();

if (oSPSite != null)
oSPSite.Dispose();
}

Best Practice #4: Whenever you create an object with a new operation, the creating application must dispose it off

C# Coding snippet

SPSite oSPSite = new SPSite("http://server");

... additional processing on SPSite ...

oSPSite.Dispose();

alternatively, this is a better approach

C# Coding snippet

using(SPSite oSPSite = new SPSite("http://server"))
{
... additional processing on SPSite ...
}

Best Practice #5: For Site.OpenWeb method, you need to dispose it off explicitly.

C# Coding snippet

String str;
SPSite oSPSite = new SPSite("http://server");
SPWeb oSPWeb = oSPSite.OpenWeb();

str = oSPWeb.Title;
str = oSPWeb.Url;

... additional processing on SPWeb ...

oSPWeb.Dispose();
oSPSite.Dispose();

Alternatively you may use the Using clause too for better readibility and automatic disposition of objects:

C# Coding snippet

String str;
using(SPSite oSPSite = new SPSite("http://server"))
{
using(SPWeb oSPWeb = oSPSite.OpenWeb())
{
str = oSPWeb.Title;
str = oSPWeb.Url;

... additional processing on SPWeb ...
}
}

Best Practice #6: An exception to the rule is that One should not explicitly dispose SPSite.RootWeb, as it is automatically disposed off.

Similary one should not explicity dispose SPContext.Current.Site and SPContext.Current.Web as they are handles automatically by Sharepoint and .NET framework.

C# Bad Coding Practice Snippet:

void SPContextBADPractice()
{
SPSite siteCollection = SPContext.Current.Site;
siteCollection.Dispose(); // DO NOT DO THIS
SPWeb web = SPContext.Current.Web;
web.Dispose(); // DO NOT DO THIS
}


C# Good Coding Practice Snippet:

void SPContextBestPractice()
{
SPSite siteCollection = SPContext.Current.Site;
SPWeb web = SPContext.Current.Web;
// Do NOT call Dispose()
}
Best Practice #7: SPControl.GetContextSite(Context) and GetContextWeb(Context) return SPSite and SPWeb respectively, they do not need an explicit call to Dispose(), they will be disposed automatically

C# Bad Coding Practice Snippet:

void SPControlBADPractice()
{
SPSite siteCollection = SPControl.GetContextSite(Context);
siteCollection.Dispose();   // DO NOT DO THIS
SPWeb web = SPControl.GetContextWeb(Context);
web.Dispose();  // DO NOT DO THIS
}

C# Good Coding Practice Snippet:

void SPControlBestPractice()
{
SPSite siteCollection = SPControl.GetContextSite(Context);
SPWeb web = SPControl.GetContextWeb(Context);
// Do NOT call Dispose()
}

Best Practice #8: SPWeb.ParentWeb  returns SPWeb, and needs to be disposed off explicitly using either Dispose() or the using clause

C# Bad Coding Practice Snippet:
void ParentWebLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
SPWeb parentWeb = outerWeb.ParentWeb; // Internal reference to SPWeb parentWeb
string sTitle = parentWeb.Title;
string sUrl = parentWeb.Url;
// SPWeb object parentWeb leaked
} // SPWeb object outerWeb.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called 
}

C# Good Coding Practice Snippet:
void ParentWebBestPractice()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
using (SPWeb parentWeb = outerWeb.ParentWeb) // Internal reference to SPWeb parentWeb
{
string sTitle = parentWeb.Title;
string sUrl = parentWeb.Url;
} // SPWeb object parentWeb.Dispose() automatically called
} // SPWeb object outerWeb.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called 
}

Best Practice #9: SPWeb.Webs returns an SPWeb object, practically used in drilling down sub-sites within a Site

C# Bad Coding Practice Snippet:
void WebsLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in outerWeb.Webs)
{
// SPWeb innerWeb leak
}
} // SPWeb object outerWeb.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called 
}


C# Good Coding Practice Snippet:
void WebsBestPractice()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in outerWeb.Webs)
{
innerWeb.Dispose();
}
} // SPWeb object outerWeb.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called 
}

Best Practice #10: AllWebs[] Indexer returns SPWeb
object that needs to be disposed to avoid aggregation of memory which
can lead to memory pressure when running on a site collection with
large number of sub sites. Practically used in Enumerating or iterating all webs in a site collection.

C# Bad Coding Practice Snippet:

void AllWebsForEachLeakBestPractices()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in siteCollection.AllWebs)
{
 // Explicit Dispose must be called to avoid aggregation of memory
}
} // SPWeb object outerWeb.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called 
}


C# Good Coding Practice Snippet:

void AllWebsForEachLeakBestPractices()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in siteCollection.AllWebs)
{
innerWeb.Dispose();   // Explicit Dispose must be called to avoid aggregation of memory
}
} // SPWeb object outerWeb.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called 
}

C# Bad Coding Practice Snippet:

void AllWebsIndexerLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
SPWeb web = siteCollection.AllWebs[0];
// SPWeb web leaked
}  // SPSite object siteCollection.Dispose() automatically called 
}

C# Good Coding Practice Snippet:

void AllWebsIndexerBestPractice()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.AllWebs[0])
{
} // SPWeb object web.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called 
}

Best Practice #11: AllWebs.Add() returns a instance of SPWeb object which needs to be disposed.

C# Bad Coding Practice Snippet:
void AllWebsAddLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
SPWeb web = siteCollection.AllWebs.Add("site-relative URL");
// SPWeb web Leaked
}  // SPSite object siteCollection.Dispose() automatically called 
}

C# Good Coding Practice Snippet:
void AllWebsAddBestPractice()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.AllWebs.Add("site-relative URL"))
{
} // SPWeb object web.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called 
}

Best Practice #12: OpenWeb() returns a SPWeb object which needs to be disposed.

C# Bad Coding Practice Snippet:
void OpenWebLeak()
{
using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())
{
// SPSite leaked !
} // SPWeb object web.Dispose() automatically called
}

C# Good Coding Practice Snippet:
void OpenWebBestPractice()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
} // SPWeb object web.Dispose() automatically called
}  // SPSite object siteCollection.Dispose() automatically called
}

Best Practice #13:new SPSite() - Instantiating SPSite objects with the new operator needs to be disposed.

C# Bad Coding Practice Snippet:
void CreatingSPSiteLeak()
{
SPSite siteCollection = new SPSite("http://moss");
// siteCollection leaked
}

C# Good Coding Practice Snippet:
void CreatingSPSiteExplicitDisposeBestPractice()
{
SPSite siteCollection = new SPSite("http://moss");
siteCollection.Dispose();
}

void CreatingSPSiteWithAutomaticDisposeBestPractice()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
} // SPSite object siteCollection.Dispose() automatically called
}

Do Not Dispose Guidance for SharePoint 2010 & 2007:(Updated on 23/2/2011):
Do not dispose the following listed objects explicitly:

•SPContext.Current.Site

•SPContext.Current.Web

•SPContext.Site

•SPContext.Web

•SPControl.GetContextWeb(..)

•SPControl.GetContextSite(..)

•SPFeatureReceiverProperties.Feature.Parent

•SPItemEventProperties.ListItem.Web

•SPList.BreakRoleInheritance()

◦Do not call list.ParentWeb.Dispose()

•SPListEventProperties.Web

•SPListEventProperties.List.Web

•SPSite.RootWeb

◦Problems may occur when SPContext.Web has equality to the SPContext.Web.. make sure you dispose of SPSite and it will cleanup sub webs automatically

•SPSite.LockIssue

•SPSite.Owner

•SPSite.SecondaryContact

•SPWeb.ParentWeb

•SPWebEventProperties.Web

Changes:

•Microsoft.SharePoint.WebControls.SiteAdminsitrationSelector.CurrentItem

◦When used with WSS 3.0 you must call Dispose(), with SharePoint Foundation 2010 you don’t.

•Event Receivers and properties.OpenWeb()

◦WSS 3.0: When you call properties.OpenWeb() the returned SPWeb will need to call Dispose()

◦SharePoint Foundation 2010: Use the newly introduced SPItemEventProperties.Web property instead of SPItemEventProperties.OpenWeb() for better performance and to avoid the need to call Dispose().

Reference taken from :

Friday, February 10, 2012

Configuration for ASP.Net Chart webpart for sharepoint


Steps for configuration of ASP.net chart controls in sharepoints
1.        Add dll in webpart project: System.Web.DataVisualization for charts.
2.        Add the below handlers in the web.config file of the application which is located in inetpub/wwwroot/wss/VirtualDirectories/<WebApplicationPortNumber>
<system.web>
<httpHandlers>
<add path="ChartImg.axd" verb="GET,HEAD,POST" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" />
    </httpHandlers>
    </system.web>

<system.webServer>
<handlers>
<add name="ChartImageHandler" preCondition="integratedMode" verb="GET,HEAD,POST" path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</handlers>
</system.webServer>

The value marked give the folder name of the temporary chart images.
 <appSettings>
    <add key="ChartImageHandler" value="storage=file;timeout=20;Url=~/wpresources/;" />
  </appSettings>

Monday, February 6, 2012

Change sharepoint server 2010 Display language from Default language to alternate language programmatically


I found a solution on a following issue to change the default language to alternate language programmatically using which the sharepoint designer's actions and conditions language doesn't change below is the javascript code:
_spBodyOnLoadFunctionNames.push('ChangeLanguage');
function ChangeLanguage()
{
//script fetches current display language
var lcid =_spPageContextInfo.currentLanguage;
//1025 language code for arabic
if(lcid.toString()!=1025)
{
var today = new Date();
var oneYear = new Date(today.getTime() + 365 * 24 * 60 * 60 * 1000);
var url = window.location.href;
//script changes current display language to arabic i.e 1025
document.cookie = "lcid=" + 1025 + ";path=/;expires=" + oneYear.toGMTString();
window.location.href = url;
}
}
If any queries do reply.
Regards,