Wednesday, December 10, 2008

Creating a sharepoint page dynamically.

The SPWeb object for a site exposes a Files property with a public Add method that allows you to add new site pages. There is an overloaded version of the Add method that allows you pass a stream object with the content of the new page. The following example demonstrates writing the contents of a new page to a Memory Stream object and then using it to create a new site page named Hello.htm.

//write out new page in memory stream.
MemoryStream stream=new MemoryStream();
StreamWriter writer=new StreamWriter(stream);
writer.WriteLine("");
writer.WriteLine("Hello, world");
writer.WriteLine("");
writer.Flush();

//add new page to site
SPWeb site=SPContext.Current.Web;
site.Files.Add("hello.htm",stream);



Let me know if you have any question.

Thanks,
Sanjay

Friday, December 5, 2008

How to create a custom e-mail alert handler in Microsoft Office SharePoint Server

This method creates a class that inherits from the IAlertNotificationHandler interface and that uses the OnNotification method. This method lets you intercept the outgoing e-mail alerts and modify them. You can access most of the properties of the alert. By using XML parsing and SharePoint object model code, you can extract all the information that you must have to modify the e-mail alert. Then, you can build the HTML stub to display the e-mail alert based on your requirements. Also, you can send the e-mail alert by using SharePoint̢۪s SendMail functionality.

public class Class1:IAlertNotifyHandler
{

#region IAlertNotifyHandler Members

public bool OnNotification(SPAlertHandlerParams ahp)
{
try
{
SPSite site = new SPSite(ahp.siteUrl+ahp.webUrl);
SPWeb web = site.OpenWeb();
SPList list=web.Lists[ahp.a.ListID];
SPListItem item = list.GetItemById(ahp.eventData[0].itemId) ;

string FullPath=HttpUtility.UrlPathEncode(ahp.siteUrl+""+ahp.webUrl+""+list.Title+""+item.Name);
string ListPath = HttpUtility.UrlPathEncode(ahp.siteUrl + "" + ahp.webUrl + "" + list.Title);
string webPath=HttpUtility.UrlPathEncode(ahp.siteUrl+""+ahp.webUrl);

string build = "";
if (ahp.eventData[0].eventType==1)
eventType="Added";
else if(ahp.eventData[0].eventType==2)
eventType="Changed";
else if(ahp.eventData[0].eventType==3)
eventType="Deleted";

build = ""+
"

"+ item.Name.ToString() +" has been "+eventType +"

"+
""+
""+
"" +
"
"+
"Modify my Settings
View "+item.Name+"View " + list.Title + "
";
string subject=list.Title.ToString() ;
SPUtility.SendEmail(web,true , false, ahp.headers["to"].ToString(), subject,build);
return false;
}
catch (System.Exception ex)
{
return false;
}
}

#endregion
}

You can put your questions/Suggestions in the comment section, I w ill try to respond as soon as possible.

Thanks,
Sanjay

Friday, November 21, 2008

Best Practices while creating custom SharePoint event handlers.

When building custom event handlers, keep the following points in mind:

1. Security:
The assembly you deploy to the Global Assembly Cache(GAC) is running with full trust. Watch out for the following:
Denial of Service attack: If a user uploads 10000 items to a list, what is the effect it will have to the systems your assembly uses.
SQL Injection attack: If a user attempts to insert SQL statements into a column of a list that your assembly uses to update a database, what mechanisms are you using to make sure the input is valid.
Cross Site scripting attack: What is the effect of adding script to a column that your assembly uses to update another area in SharePoint?


2. Performance:
Watch out for the following:

Load: What burden are you placing on your web front end servers to run the assembly each time an event occurs? Use performance counters to determine this.
Long Running Operations: Consider creating a custom SharePoint timer job. Kick off/ Schedule the Timer Job from the event rather than running all the logic inside the event. This will allow you to use the features of SharePoint to view whether the Timer Job ran successfully.
Sync vs Async Events: Synchronous events have to wait until your code completes before returning the page, whereas Asynchronous events show the page immediately.


3. Error Handling:
When using synchronous events and you decide to cancel an event, let the user know why the event was cancelled. For example, update a Task List with a message why it failed.
Log your errors so that you can determine what issue is occurring when your system is in production environment.

4. Connections
Cater for external systems being down when you are trying to connect to them. Don’t let your code / solution go belly up because you cannot connect to a database.

5. Bulk Operations
The MSDN documentation mentions that event handlers will not fire when bulk operation is occurring. For example, when a new list is created, the FieldAdding event will not fire.

6. Disabling event firing
DisableEventFiring()
Do_my_changes
EnableEventFiring()

Limitations of Event Handler in SharePoint
There is no event handlers for web.

Strangely there is no “SiteAdding”, “SiteAdded” event. However, if you really need this event you could create a “feature” to accomplish this. Features in SharePoint have a “FeatureActivated” event, where you could perform an action on creation of a site.

SharePoint 2007 Limits

Site collection
50,000 per content database
Total farm throughput degrades as the number of site collections increases.

Site collection
150,000 per Web application
This limit is theoretical, and is dependent largely upon:
Performance of the database server on which the configuration database resides.
Performance of the Web servers in the farm.
Network bandwidth between the Web servers and the database server.
This is not a hard limit, and assumes a single database server. Your environment may not be able to host this many site collections per Web application. Distributing content databases across additional database servers can increase the effective limit of the number of site collections per Web application. You should perform testing to determine the actual effective limit in your environment.

Web site
250,000 per site collection
You can create a very large total number of Web sites by nesting the subsites. For example, 100 sites, each with 1000 subsites, is 100,000 Web sites. The maximum recommended number of sites and subsites is 125 sites with 2,000 subsites each, for a total of 250,000 sites.

Subsite
2,000 per Web site
The interface for enumerating subsites of a given Web site does not perform well as the number of subsites surpasses 2,000.

Document
5 million per library
You can create very large document libraries by nesting folders, using standard views and site hierarchy. This value may vary depending on how documents and folders are organized, and by the type and size of documents stored.

Item
2,000 per view
Testing indicates a reduction in performance beyond two thousand items. Using indexing on a flat folder view can improve performance.

Document file size
50MB (2GB max*)
File save performance is proportional to the size of the file. The default maximum is 50 MB. This maximum is enforced by the system, but you can change it to any value up to 2 GB.
Library, file save performance

List
2,000 per Web site
Testing indicates a reduction in list view performance beyond two thousand entries. For more information about large lists, see White paper: Working with large lists in Office SharePoint Server 2007.

Field type
256 per list
This is not a hard limit, but you might experience list view performance degradation as the number of field types in a list increases.

Column
2,000 per document library
4,096 per list
This is not a hard limit, but you might experience library and list view performance degradation as the number of columns in a document library or list increases.
Library and list view

Web Part
50 per page
This figure is an estimate based on simple Web Parts. The complexity of the Web Parts dictates how many Web Parts can be used on a page before performance is affected.

Managed path
20 per Web application
20 managed paths is a soft limit. Managed paths are cached on the Web server, and CPU resources are used to process incoming requests against the managed path list. You should test for performance before exceeding 20 managed paths in a single Web application.
Web application


Users in groups
2 million per Web site
You can add millions of people to your Web site by using Microsoft Windows security groups to manage security instead of using individual users.

User profile
5 million per farm
This number represents the number of profiles which can be imported from a directory service, such as Active Directory, into the people profile store.

Indexed documents
50,000,000 per content index
Office SharePoint Server 2007 supports 50 million documents per index server. This could be divided up into multiple content indexes based on the number of SSPs associated with an index server.

Content sources
500 per SSP*
This is a hard limit enforced by the system.
Start Addresses
500 per content source*
This is a hard limit enforced by the system.

Alerts
1,000,000 per SSP
This is the tested limit.

Scopes
200 per site
This is a recommended limit per site. We recommend a maximum of 100 scope rules per scope.

Display groups
25 per site
These are used for a grouped display of scopes through the user interface.

Crawl rules
10,000 per SSP
We recommend a maximum 10,000 crawl rules irrespective of type.

Keywords
15,000 per site
We recommend a maximum of 10 Best Bets and five synonyms per keyword.

Crawled properties
500,000 per SSP
These are properties that are discovered during a crawl.

Managed properties
100,000 per SSP
These are properties used by the search system in queries. Crawled properties are mapped to managed properties. We recommend a maximum of 100 mappings per managed property.

SPList with SPQuery

The OM was used to create an SPQuery object that contained the query criteria. That object was then used to against an instance of the list in a SPList object. The results of the query were returned by calling the GetItems method on the SPList object.
The following sample code was used for this method.

'get the site
Dim curSite As SPSite = New SPSite("http://myPortal")

'get the web
Dim curWeb As SPWeb = curSite.OpenWeb()

'create our query
Dim curQry As SPQuery = New SPQuery()

'configure the query
curQry.Query = "
Hotel
"
curQry.RowLimit = 100

'get our list
Dim curList As SPList = curWeb.Lists(New Guid("myListGUID"))

'get the collection of items in the list
Dim curItems As SPListItemCollection = curList.GetItems(curQry)

'enumerate the items in the list
For Each curItem As SPListItem In curItems
'do something with each match
Next

SPList with For/Each

The Office SharePoint Server 2007 object model (OM) was used to retrieve the list into an SPList object. Each item in the list was then enumerated with a For/Each loop until items were found that matched the search criteria.
The following sample code was used for this method.

'get the site
Dim curSite As SPSite = New SPSite("http://myPortal")

'get the web
Dim curWeb As SPWeb = curSite.OpenWeb()

'get our list
Dim curList As SPList = curWeb.Lists(New Guid("myListGUID"))

'get the collection of items in the list
Dim curItems As SPListItemCollection = curList.Items

'enumerate the items in the list
For Each curItem As SPListItem In curItems
'do some comparison in here to see if it's an item we need
Next