Custom SharePoint Solutions Best Practices

Sometimes third-party tools are used for some functionality and developers need to refer to them in the SharePoint projects. For example, as shown in the figure below, a single DLL is referenced by two SharePoint projects in Visual Studio. After building the WSP solutions the same DLL will be included in each of two WSPs. Everything will work fine if these two WSPs are deployed in a single SharePoint Farm with GAC deployment since both WSPs will deploy the same DLL in the GAC. The problem will occur when retracting or removing one solution. The other WSP will fail to work since it will not find the referenced DLL in the GAC.

Packagaing-External-Dependencies.jpg

Figure: Packaging External Dependencies, the wrong way

As a best practice, package your external dependencies to a new WSP.

The solution to this problem is to exclude the DLL from both WSPs and create a new WSP dependency solution for the referenced DLL. As a result the referenced DLL will not be included in any of the two WSPs.

To package a new WSP for the referenced DLL, the developer needs to create another new Visual Studio SharePoint project that will just include the required DLL and any other dependencies as shown in the figure below.

Packagaing-External-Dependencies1.jpg

Figure: Packagaing External Dependencies, the right way

SharePoint 2013 COM Components

SharePoint uses COM components for some of its core features. SPSite and SPWeb are COM objects that access the content database. The figure below explains the call flow. OWSSVR.dll is the COM component that manipulates the Content DB and is responsible for building the SQL queries at runtime and calling the stored procedures from the SharePoint content database.

SharePoint 2013-Call-Flow.jpg

Figure: SharePoint 2013 Call Flow

The implication of this is there are unmanaged objects being created all the time and those objects cannot be cleaned up automatically by the .NET garbage collector. Hence it is important to call Dispose() or Close() on these unmanaged resources when we have finished using it. This will prevent unmanaged memory leaks and not affect server performance.

There are exceptions though. If the SPSite and SPObject are called through SPCurrentContext that is a managed class then Dispose need not be called. There is a free tool available called SPDisposeCheck that helps developers and administrators to check custom SharePoint solutions that use the SharePoint Object Model to help measure against known Microsoft dispose best practices.

Apps license checking

It is strongly recommended for security purposes that you place the code that performs the app license check somewhere outside the reach of possible tinkering. Instead of using JavaScript code only use server-side code to query the Office Store verification web service. Do not perform app license checks on every page of your app. App performance can degrade by constant querying of app license token.

Use SPMonitoredScope

Developers should use SPMonitoredScope to wrap their code. They should also use TraceSeverity Level to conditionally scope the code so that events are written out in the event log file. This helps them to monitor and manage the performance of their components as they deploy from development to UAT to production. They can use the Developer Dashboard tool to check if custom code is the culprit taking more time to execute.

One thing to note is that even if developers use SPMonitoredScope, if the code is a sandbox component or in a cloud then the output from it will not be captured in the Developer Dashboard.

The reason it doesn't get captured is that sandbox components execute in a completely different process from the page request. As a result, it can't pipe the tracing information back into the page processing event pipeline. Only full trust farm solutions can use this class.

Security: SafeControls and Cross-Site-Scripting SafeGuard

From a security point of view, every Web Part acts in the context of the current user hence its security against SharePoint's data is based on the current user's permissions. However, SharePoint's data security may not be the ultimate measure of a secure solution. For example, an authorized user could insert a Web Part that represents a risk for the client browser or for the server environment hosting the SharePoint solution. Imagine what would happen if a user uploads a custom Web Part that consumes a lot of CPU resources (perhaps 80%) due to a bug or even malicious intent. Any SharePoint front-end server that loads and executes this Web Part would block any further functionality, or at least have its performance seriously degraded.

To avoid such issues, SharePoint provides safe controls. In fact, SharePoint will load and execute only authorized Web Parts based on a list of SafeControls declared in the web.config of the current web application. When you deploy a Web Part solution at the farm level make sure to mark the web part class as a SafeControl in the web.config of the site where the control is deployed.

If a user tries to load a page that hosts a Web Part or a control not marked as a SafeControl, the load will fail, but the SharePoint environment will remain stable and secure.

The SafeControl tag also defines a SafeAgainstScript attribute with a Boolean value that allows configuring a feature called Cross-Site-Scripting SafeGuard.