Monday, December 5, 2011

About Event Receivers and Event Handlers

Synchronous and Asynchronous Events.
* Synchronous events can trap an item, document library or site before it is deleted,added or updated.
eg, ItemAdding, ItemUpdating,ItemDeleting etc.
* Asynchronous events can trap an item, document library or site when it is added,deleted or updated.
eg, ItemAdded, ItemUpdated,ItemDeleted etc.


We create Event Recivers to handle these events. An event receiver basically, is a piece of managed code that is launched in response to an event that takes place within SharePoint.

SharePoint Object Model exposes several event classes inherited from Microsoft.SharePoint assembly. There are three main event classes:

SPItemEventReceiver
SPListEventReceiver
SPWebEventReceiver


Each class includes both synchronous and asynchronous methods to work with Item, List or Web Level.
Some of the Good Examples are on :
http://www.codeproject.com/KB/sharepoint/ExtendingSPS.aspx
http://msdn2.microsoft.com/en-us/library/ms453149.aspx

Display List Data with SPGridView

Steps:
1. Drag and drop SPGridView and SPDataSource from toolbox. (If you dont have them, right click on tabs and click on choose items and select GridView and SPDatasource).

2. Write the following in Code Behind for binding SPGridView with List Data.

protected void Page_Load(object sender, EventArgs e)
{
SPSite mySite = SPContext.Current.Site;
SPWeb myWeb = mySite.OpenWeb();
SPList List = myWeb.Lists["Mylist"];
SPDataSource1.List = List ;
GridView .DataSource = SPDataSource1;
GridView .DataBind();
}

Sunday, December 4, 2011

Power Shell Commands Links

Windows PowerShell Commands for SharePoint 2010 part1
.
http://mysharepointwork.blogspot.com/2010/03/windows-powershell-commands.html

Windows PowerShell Commands for SharePoint 2010 Part2

http://mysharepointwork.blogspot.com/2010/06/sharepoint-2010-windows-powershell.html

Sharepoint Debugging (To find out the exact error instead of sharepoint throwing a plain yellow page with "Unexpected Error" message)

Here are the steps to follow and trace the exact error from any share point web application.


These changes are recommended only in development environment.

Open the sharepoint site web.config file

Find out the tag “<SafeMode” set the callstack attribute value to true as shown in bold style, by default it is False.

<SafeMode MaxControls="200" CallStack="True" DirectFileDependencies="10" TotalFileDependencies="50" AllowPageLevelTrace="false">

Find out the tag  “<customErrors” set the mode attribute value to Off.

  <customErrors mode="Off" />


Find out the tag   <compilation” set the debug attribute value to true.

 <compilation batch="false" debug="true">

Finally reset Internet Information Server (IIS)
 

When to use SPContext.Current.Web and when to use SPControl.GetContextWeb(Context)

When your code file is a custom aspx, or code behind aspx.cs page hosted in a virtual directory
You can make use of :

SPWeb oWebSite = SPContext.Current.Web; or
SPWeb oWebSite = SPControl.GetContextWeb(Context);

to get reference to your current site.


If your .aspx page inherits from LayoutsPageBase instead of Page, you can use the Site or Web properties of SPContext.Current

If you want to use SPControl class to get reference to the current site or web object from  your .aspx page inherited from LayoutsPageBase

you can use the Microsoft.SharePoint.WebControls.LayoutsPageBase.Context property as the parameter to the GetContextWeb(HttpContext) and GetContextSite(HttpContext)

Eg:-
SPWeb oWebSite = SPControl.GetContextWeb(Microsoft.SharePoint.WebControls.LayoutsPageBase.Context);

Handling AccessDenied Exception in MOSS

The SPUtility.HandleAccessDenied method provides the functionality to redirect users to the standard "Access Denied Page" pragmatically, thus asking them to re-logon. One of the scenarios of such usage is the public sites, where access to the standard SharePoint specific pages still exists and you want to block those pages
However, you can handle access denied exception via SPSecurity.CatchAccessDeniedException = true
Access deined exception is handled by sharepoint platform and user will be redirected to _layouts/AccessDenied.aspx page if user doesnt have permission to perform that task. This might casue usability problem in some cases. You can handle access denied exception in your code by setting CatchAccessDeniedException value to true.
Following code snippet shows how to handle access denied exception:

bool catchException = SPSecurity.CatchAccessDeniedException;
SPSecurity.CatchAccessDeniedException = false;
try
{
//updating list item
SPList list = SPcontext.Current.Web.List["TestList"];
SPListItem item = list.Items[0];
item["title"] = "Some value";
//If user doesnt have permission, exception will be thrown
//If value of CatchAccessDeniedException is true, then user will be
//redirected to AccessDenied.aspx page
item.Update();
}
cach(Exception ex)
{
//Your custom error message can be shown here
}
finally
{
//reset the flag to original value
SPSecurity.CatchAccessDeniedException = catchException;
}

Friday, April 15, 2011

Never use SPList.Items.GetItemById(ID)

NEVER EVER use List.Items.GetItemById(ID) or List.Items[ID]
Use List.GetItemById(ID) instead.
Under normal conditions when there are relatively few items in a list then all will seem to go well.  However, as time goes by and the list item count increases then you could find that
your SharePoint site is grinding to a halt.  This will be characterised by the application pool growing in size.
SCENARIO
A single document library well structured with folders has 680,000 documents in it.  As per MS recommendations no single view or folder has more than 2000 items.
A custom workflow was added to the site and suddenly the application pool climbs to 11Gb and the site stops responding.  The reason? The workflow includes the statement
list.Items.GetItemById(id);
This will cause the whole list to be enumerated,

using (SPSite site = new SPSite(<a href="http://someurl">http://someurl</a>))
{
    using (SPWeb web = site.RootWeb)
    {
        // Test 1
        DateTime start = DateTime.Now;
        SPListItem item = web.GetListItem("/someitemUrl"),,);
        Console.WriteLine("Time for web.GetListItem():{0}",DateTime.Now-start);
        Console.WriteLine(item.Title);
 
        // Test 2
        start = DateTime.Now;
        item = web.Lists[item.ParentList.ID].GetItemById(item.ID);
        Console.WriteLine("Time for List.GetItemById():{0}", DateTime.Now - start);
        Console.WriteLine(item.Title);
 
        // Test 3
        start = DateTime.Now;
        Console.WriteLine("This is going to take a very very very very loooooonnnnnnnngggggggggg time! Kill it now");
        item = web.Lists[item.ParentList.ID].Items.GetItemById(item.ID);
        Console.WriteLine("Time for List.Items.GetItemById():{0}", DateTime.Now - start);
        Console.WriteLine(item.Title);
 
        // Test 4
        start = DateTime.Now;
        Console.WriteLine("This is going to take a very very very very loooooonnnnnnnngggggggggg time! Kill it now");
        item = web.Lists[item.ParentList.ID].Items[item.ID];
        Console.WriteLine("Time for List.Items[]:{0}", DateTime.Now - start);
        Console.WriteLine(item.Title);
 
    }
}
 Test 1 took 1.363194s
Test 2 took 0.0087885s (very impressive)
Test 3 and 4 failed to complete due to memory resource failure