Sunday, February 27, 2011

SPSecurity.RunWithElevatedPrivileges Access denied issue

SPRunWithElevatedPrivileges allows you to run your SharePoint code in the context of the App Pool identity account.

Look at the piece of code below:


function void ListItemUpdate(Guid guId)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite site = SPContext.Current.Site;
SPWeb web = SPContext.Current.Web;
web.AllowUnsafeUpdates = true;

SPList list = web.Lists["Products"];
SPListItem item = list.Items[guId];
item["ProductName"] = "Apple iPhone 4";
item["ProductPrice"] = "199";

item.Update();

web.AllowUnsafeUpdates = false;
});
}

So when a user with Read access tries to execute the above code, he gets an Access denied error, even after the code having the RunWithElevated Privileges set.

Lets examine, look at the code highlighted in yellow above. SPContext.Current.Site and SPContext.Current.Web runs the List Item update code in the context of the currently logged in user and not in the context of the App Pool identity.

Solution: Solution is to re-open new SPSite and SPWeb objects within the SPSecurity delegate block, lets rewrite the above code and fix the issue:

function void ListItemUpdate(Guid guId)
{
Guid siteId = SPContext.Current.Site.Id;
Guid webId = SPContext.Current.Web.Id;

SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(siteId))
{
using (SPWeb web = site.OpenWeb(webId))
{
web.AllowUnsafeUpdates = true;

SPList list = web.Lists["Products"];
SPListItem item = list.Items[guId];
item["ProductName"] = "Apple iPhone 4";
item["ProductPrice"] = "199";
item.Update();

web.AllowUnsafeUpdates = false;
}
}
});
}

Running this piece of code fixes the Access denied issue and allows the code to run under AppPool identity.

Wednesday, February 23, 2011

SharePoint 2010 - Do not dispose guidance for SharePoint objects

Do not dispose the following listed SharePoint objects explicitly: (Applicable for both SharePoint 2010 and SharePoint 2007)

•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

Few important changes for Dispose rules in SharePoint 2010:
•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: http://blogs.msdn.com/b/rogerla/archive/2009/11/30/sharepoint-2007-2010-do-not-dispose-guidance-spdisposecheck.aspx

Sunday, February 20, 2011

XML and XSL transformation control for SharePoint 2010

The ASP.NET control control for SharePoint enable users to provide their XML and XSL files, spitting out the resulting HTML based on the two control parameters.

1. Copy and paste the code below in your custom SharePoint page:
<div>
<asp:Xml runat="server" id="xmlEmployee" DocumentSource="/_layouts/SPFix/Employee.xml" TransformSource="/_layouts/SPFix/Employee.xsl">
</asp:Xml>
</div>

2. The Document Source behavior takes an XML file path and Transform Source takes an XSL file path
3. You can see the resulting HTML spitted out to the browser when you hit your SharePoint custom page.

Quickest way is to try using SharePoint Designer as per the best practice you need to create a Visual Studio solution for your SharePoint pages.

Saturday, February 19, 2011

StringWriter and HTMLTextWriter objects to emit HTML in custom Webparts

You could also use StringWriter and HTMLTextWriter objects to write HTML to the Web part rather than the LiteralControl.

For example, the following code creates a simple StringBuilder object, then writes that through using the
StringWriter and HtmlTextWriter objects:

StringBuilder sb = new StringBuilder();
sb.AppendLine(“<table border=’0’><tr><td>”);
StringWriter spStrWriter = new StringWriter(sb);
HtmlTextWriter htmlTxtWriter = new HtmlTextWriter(spStrWriter);
Page.RenderControl(htmlTxtWriter);

Admittedly, the use of multiple literalcontrol objects is not the most elegant of ways to emit HTML
when rendering Web parts. See an example usage of Literal Controls mentioned below:

StringBuilder sb = new StringBuilder();
sb.AppendLine(“<table border=’0’><tr><td>”);
this.Controls.Add(new LiteralControl(sb.ToString()));

ASP.NET provides a rich framework for writing HTML out to the page, which includes the HtmlTextWriter class. We can leverage this while writing custom webparts

How to register Javascripts within SharePoint page programmatically

When you’re integrating script within a SharePoint page, you can use the ClientScriptManager object to add and manage scripts within a Web application. For example, the following code snippet shows a simple method that ensures only one instance of each script is added to a page:

public static void RegisterScript
(ref ClientScriptManager csm,
string key, string url)
{
if (!csm.IsClientScriptBlockRegistered(key))
csm.RegisterClientScriptInclude(key, url);
}

For more information on the ClientScriptManager, see http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.aspx.

Thursday, February 3, 2011

Visual Studio 2010 and FxCop Integration

Visual Studio 2010 Premium and Ultimate Editions already have FxCop installed by default under the Code Analysis section in the Build menu option, see snapshot below:


You can configure your own Rules by right clicking on your Project -> Properties -> Code Analysis -> Set the Rule Set option as shown in the snapshot below:


To run the Code Analysis section, right click on your Project -> Run Code Analysis as shown in the snapshot below:


You will see the Code Analysis Results in the Error List window as shown in the snapshot below:
(Check for both Errors and Warnings and fix them)


I hope this helps.

SPDispose Check utility - Integrate with Visual Studio 2010

SPDisposeCheck utility checks whether you have disposed the unmanaged SPSite and SPWeb objects correctly or not. Its a tool that every SharePoint developer needs to have integrated in their Visual Studio boxes.

I have prepared a list of Best Practices for Disposing SharePoint objects: http://www.sharepointfix.com/2008/12/best-practices-disposing-sharepoint.html

Guidelines to integrate SPDisposeCheck with Visual Studio Solution:

1. Download the SPDisposeCheck.exe utility from: http://download.microsoft.com/download/B/4/D/B4D279A0-E159-40BF-A5E8-F49ABDBE95C7/SPDisposeCheck.msi

2. Open your Visual Studio environment and follow the steps as specified:
a. Go to Tools -> External Tools -> Add
b. Enter Title as SPDisposeCheck
c. Command : C:\Program Files (x86)\Microsoft\SharePoint Dispose Check\SPDisposeCheck.exe
d. Arguments : $(TargetName)$(TargetExt)
e. Initial Directory : $(TargetDir)
f. Check mark the Output window checkbox and
g. Click on the Ok button

See snapshot below:


3. Open your Visual Studio solution project and Build it.

4. Select Tools -> SPDisposeCheck:


5. Open the Output window and you should be able to see a set of messages like this:


6. It also shows up the errors in the Visual Studio Error Messages section as follows:

7. You can even configure additional SPDispose Check settings within Visual Studio 2010 by selecting "SharePointDispose Check" link under Tools, see snapshot below:


Let me know if it helps.