Tuesday, October 1, 2013

SharePoint 2010 Custom Development Best Practices

If you are new to SharePoint 2010 development, building custom solutions based on the SharePoint 2010 framework is never easy. Sometimes list of types of custom components you can build on top of SharePoint 2010 Foundation framework is overwhelming. For the novice or even for the experienced SharePoint developers, it would be easy to get lost into specifics of the SharePoint 2010 development. Every kind of custom SharePoint components like web parts, visual web parts, application pages, site pages, master pages, page layouts, content types, list definition, site definitions, workflows, event receivers, lists, content types, field types, etc. brings their own special challenge.

1.    Don’t ever change the files in the out of the box SharePoint Root (14-Hive) directory. 
2.    Never build your SharePoint development environment on the host machine. Use the Virtual
     Machine   instead. Virtualized environment promotes portability, playground as sandbox, 
     and allows quick and easy way to snapshot the development environments. 
3.    Leverage WSPs (solutions and feature framework) while deploying and packaging code from development to staging to production environment. 
4.    Make sure solutions have proper consistent naming convention e.g. OrganizationName.BusinessSolution. 
5.    Make sure solutions have proper feature name and description. Feature name and description would be visible on the site collection and site features page. 
6.    Make sure custom code is compiled and packaged in release mode. 
7.    Use SPUtility, SPUrlUtility, and HttpUtility if you can. e.g. Use SPEncode to encode the HTML and URL encoding. 
8.    Since URLs can change between different environments, use site.serverrelativeurl instead of site.url to build the URL in code. 
9.    Don’t forget to dispose the newly created SPWeb and SPSite objects. If you create an object using “new”, you must dispose it. (e.g. SPSite site = new SPSite(url) or SPWeb web = site.OpenWeb()). Although SPWeb and SPSite objects use minimal managed memory, it allocates substantial unmanaged memory. You must free up unmanaged memory allocated during creation of SPWeb or SPSite objects by disposing the objects. Best practice is to instantiate objects with “using” keyword in C#.  (e.g. using (SPSite spSite = new SPSite(url))).  Additionally, always run solution against SPDisposeCheck utility to ensure disposing all the objects properly before production deployment. (http://code.msdn.microsoft.com/SPDisposeCheck) 
10.  Don’t dispose the SPContext.Current.Site or SPContext.Current.Web object. It will be disposed automatically by the runtime. e.g. Do not use “using” keyword with the object referenced through SPContext  (e.g. don’t use using(SPWeb spWeb = SPContext.Current.Web)) 
11.  Don’t use SPContext.Current.Site or SPContext.Current.Web objects in the Feature Receiver to access current instance of SPWeb or SPSite . If you ever try to activate/deactivate features using PowerShell, SPContext would fail because it’s available only in the browser context. Instead use properties.Feature.Parent to access current instance of SPWeb or SPSite object. For Site collection level feature, it would return SPSite and for web level feature, it would return SPWeb object. (e.g. use using (SPWeb spWeb = (properties.Feature.Parent as SPWeb))) 
12.  Plan to install SharePoint Manager 2010 from the codeplex. It is a SharePoint object model explorer and enables you to browse every site properties on the local farm by browsing through SharePoint Internals.(http://spm.codeplex.com/) 
13.  Use SharePoint Developer Dashboard to Investigate the Page Performance bottlenecks. It gives detailed information on resource usage, performance, user interactions and error trapping. Use SPMonitoredScope code block to generate the custom logged counters on the Developer Dashboard. Please note that you can enable the Developer Dashboard at the farm level and never enable it in production environment. 
14.  Use SPGridView instead of standard ASP.NET Gridview to inherit the SharePoint CSS, Look and Feel, and Column filtering mechanism. On other side, Use standard ASP.NET Gridview instead of SPGridView to full control over the tabular design and functionality. 
15.  Use the List Event Receivers to execute the code immediately. Workflows can perform similar function but it will run as a timer job which may delay the code execution. 
16.  Use SharePoint Site Property Bag to classify the sites and persist site level metadata. You can either use SPWeb.Properties (Microsoft.SharePoint.Utilities.SPPropertyBag Object) or SPWeb.AllProperties (System.Collections.Hashtable Object) or Site      Property Bag Configuration Tool – http://pbs2010.codeplex.com/. SPWeb.Properties considered as legacy approach since it stores key and value in lowercase. SPWeb.AllProperties keeps casing of key and value intact. If you don’t care about the persisting case, plan to use older method SPWeb.Properties instead of newer method SPWeb.AllProperties. Here is the reason why – http://www.novolocus.com/2010/12/22/stupid-spweb-properties/ 
17.  Don’t build State Workflows in the SharePoint 2010 using Visual Studio 2010.  State workflows may NOT be upgradable because they are not available in the .NET 4.0 which might be foundation framework for the next version of SharePoint. 
18.  Use field controls on the WCM sites instead of web parts because you won’t have page history with web parts. 
19.  For the list data access using server side object model, Use LINQ if you can, CAML if you must. Another argument is – Use CAML for fastest performance and LINQ for object oriented development. 
20.  Do not instantiate SPWeb, SPSite, SPList, or SPListItem objects within a list event receiver. It would cause significant performance overhead due to additional round trips to the database and fail other registered event receivers during subsequence update calls. Instead retrieve the SPWeb or SPListItem from SPItemEventProperties. (e.g. use SPWeb web = properties.OpenWeb() or SPListItem item = properties.ListItem) 
21.  Do not use SPList.Items while accessing list items using server side object model and try to avoid SPList.Items in a loop expression. SPList.Items iterates through all list items from all subfolders and all fields in the list item. To retrieve the list items, instead use SPList.GetItems(SPQuery query). 
22.  Avoid deploying DLLs to the GAC (this has risks because of security override), instead deploy it to the web application IIS bin directory and use custom CAS policies. 
23.  Target farm level solutions to the specific web application instead of deploying to all web applications unless you are deploying new feature to all the applications in the farm. This way custom feature for the specific web application won’t available on site collection features page or site features page on all the web applications in the farm. 
24.  Build Sandboxed solutions over farm level solutions for site collection specific custom solutions to balance business agility and IT stability. Understand the limitations of the sandbox solutions. Create site collection resource quota templates in the central administration. Another argument against sandbox solutions is it has resource quota points estimation issues for heavily collaborated sites. 
25.  Plan to disable the SharePoint Designer at the farm level and enable at the web application and site collection level as needed. 
26.  Instead of Custom Site Definition, use Web Template or Feature Stapling capabilities to add custom features on the out of the box site definition. I would also prefer Custom Coded Site Templates from scratch by creating site based on team or blank site template and activate features as needed. Also, word of caution – Never change out of the box site definition. 
27.  Deployment discipline – During the deployment and retraction process while updating or upgrading custom solutions, please use the correct older version of WSPs to retract the solution before deploying or upgrading the custom code with newer version of WSPs. This would ensure activating or deactivating features reference correct version of WSPs. 
28.  Although the CSOM, the REST interface, and the SharePoint ASP.NET Web services are all available when you develop server-side code, the use of these APIs in server-side code is only recommended for accessing data from another farm. Using the server-side object model is more efficient than using any of the client-side APIs.
   

Hope it will be helpful.
Configuring the User Profile Service in SharePoint 2010

Introduction:
User profiles provide detailed information about individuals in your organization. A user profile organizes and displays all the properties as well as documents and other items that are related to each user. In order to effectively use User Profile Services in SharePoint 2010, it should be properly configured.

Solution:
To configure the User Profile Service, complete the following steps to use User Profile features.

I. Configure the Managed Metadata Service
II. Create User Profile Service Application
III. Configure User Profile Service
IV. Configure the Synchronization Connections
V. Configuring a Synchronization Timer Job
VI. Manage User Profile/Properties after completing above configurations

I. Managing Metadata Service

The User Profile service requires that the Managed Metadata Service is setup and configured first. The Managed Metadata service allows you to utilize managed metadata and provides you with the ability to share content types across sites.
1. To configure the Secure Store Service, go to:
CA -> Application Management -> Manage service applications.
2. Click New and select “Managed Metadata Service.”
3. Enter the corresponding information for each field (Name, Database Server, Database Name, Application Pool Identity, etc.), then click the “Create” button.
4. Lastly, enter CA > System Settings > Manage services on server and start the Managed Metadata Web Service.
5. So, the first step is completed. The next step is to configure User Profile Services on server.

II. Creating a User Profile Service

User Profile Services is the service that all UPS requests pass through.
1. To start with the second step, enter:
CA -> System Settings -> Manage services on server.
2. Scroll down and find “User Profile Service“.
3. Make sure the status of the service is displayed as “Started.” If it is stopped, then start it.
4. Starting the service will activate the service, which is a requirement prior to creating the service application.
5. To create and configure the User Profile service application, re-enter:
CA -> Application Management -> Manage service applications.
6. By default, every web application takes the default service application, but for our purpose we need to create a new User Profile service application.
7. On the ribbon, click on the Arrow below “New” and select “User Profile Service Application.”
8. Enter an appropriate application name.
9. In the “Application Pool” area, we can create a new application pool or choose an existing one.
10. For our purposes, we will create a new application and configure it with an appropriate security account.
11. We need to make sure the service account has sufficient rights on all data sources as well as network sources.
12. After filling in all details, click the “Create” button
13. Specify the Profile Database, the Synchronization Database, the Social Tagging Database, and the corresponding Profile Synchronization Instance Server.
14. Then click the “Create” button.

III. Configuring Synchronization Service

1. A User Profile service application will be created, which is “User Profile Service Application_test.”
2. We can see the status of above service is Started.
3. Goto CA -> System Settings -> Manage services on server.
4. Scroll down and find “User Profile Synchronization Service“.
5. Make sure the status of the service is displayed as “Started.” If it is stopped, then start it.
6. Starting the service will activate the service, which is a requirement prior to creating the service application.
7. Select “User Profile Service Application_test” as the User Profile Application and input the valid password of account, then click the “OK” button.
8. Before configuring the User Profile Service, we have to make sure the Forefront Identity Manager Services (FIM) are correctly configured and started in the Local System Services.

IV. Configure the Synchronization Connections.

1. Configure the User Profile Connection by going to:
CA -> Application Management -> Manage service applications.
2. Select “User Profile Service Application_test” user profile and click “Manage” on the ribbon menu.
3. There will be multiple sections related to User Profile.
4. For our purposes, click on “Configure Synchronization Connections.”
5. Click “Create New Connection.”
6. Enter valid values for the various fields Connection NameTypeAuthentication Provider TypeAccount Name and Password.
7. Set the port with default value 389.
8. Click on “Populate Containers” and select several OU in Active Directory (the selected containers will be treated as synchronized object), then click the “OK” button.
9. The Synchronization connection has been successfully created.
10. We can now easily setup connection filters against our Active Directory User Profile connection by clicking on the connection that was just created and selecting “Edit Connection Filters.”
11. Specify and add any User or Group exclusions and then click OK.
12. Complete above steps, we will configure a Synchronization Timer Job.

V. Configuring a Synchronization Timer Job

1. Enter CA -> Application Management -> Manage service applications.
2. Select “User Profile Service Application_test” user profile and click “Manage” on the ribbon menu.
3. Click “Configure Synchronization Timer Job.”
4. Enable the timer job and then start profile synchronization.
5. Enter CA -> Monitoring -> Check job status to see the profile synchronization status.

VI. Manage User Profile/Properties

1. Finally, enter into Manage User Profiles and search for users – user information does not display by default, so you need to search them.
2. We also can add, edit, or delete user profiles to ensure that all the necessary Active Directory attributes were successfully imported.
We have now successfully completed a User Profile Synchronization!

Thursday, January 3, 2013

Using Session State in SharePoint 2010

SharePoint 2010 uses two services related to session state that have similar names but are separate and have different purposes.
  1. ASP.NET session state may be used on SharePoint 2010 pages. This service is automatically disabled in normal installations of SharePoint 2010; it may be enabled using the instructions below. Once enabled, it appears on the Service Applications page as “SharePoint Server ASP.NET Session State Service.”
  2. The State Service service application is designed for and only available to Office internal components such as InfoPath Forms Services and Visio Services. This service is automatically enabled in typical installations of SharePoint 2010 and is not related to ASP.NET session state. It appears on the Service Applications page as “State Service.”
To enable ASP.NET session state:
  1. Enter the following PowerShell command in the SharePoint 2010 Management Shell window:
    Enable-SPSessionStateService –DefaultProvision
  2. On each web application for which you want to use session state, edit the web.config file and set the enableSessionState property of the pages element as follows:
Guidelines for using SharePoint Server ASP.NET Session State:
  1. This session state may be used by custom code in web parts and other page-hosted controls.
  2. Session state information is stored in a configurable SQL database; this implies the following:
    1. Load-balancer affinity is not required.
    2. Heavy use of session state must be included in database/capacity planning. By default, the session state database is created on the same database server hosting the SharePoint 2010 farm configuration database. This can be changed to place it on another server; this can be done at a later date if necessary. To move it to another SQL server, it should first be disabled, then enabled again with different configuration that points to the other server.
  3. When enabled, Session state is available to the whole 2010 farm. Each web application can choose to enable it for use on ASP.NET pages (enableSessionState="true").
  4. Session state is partitioned using the root URL. This means that different web applications will have different session state objects; a web part can only access the session state object available to it. If host header site collections are used, then different session objects will be used for each site collection (the browser will have multiple session ids in different cookies).
The Enable-SPSessionStateService cmdlet creates a session state database, installs the ASP.NET session state schema, and updates the Web.config files on the farm to turn on the session state service.

use Get-Help Enable-SPSessionStateService –full for more information.

If the DefaultProvision form of the command is used, all default settings are used. These are:

  • DatabaseName = “SessionStateService_
  • DatabaseServer = the same database server as the SharePoint 2010 configuration database
  • DatabaseCredentials = Integrated Windows Authentication

If the DatabaseName form of the command is used, then these parameters may be set explicitly. If some of the parameters are not included, they default as above. To set specific credentials for accessing the session state database, note that this allows you to specify a SQL Authentication credential only, not a Windows credential. Then, use the Get-Credential command to create a PSCredential object from a username and password, then use that object as the argument of the DatabaseCredentials parameter.

After this service is enabled, “SharePoint Server ASP.NET Session State Service” will appear on the Service Applications management page.