SharePoint 2013 and Sharepoint 2010 Site Pages With Inline Code

Recently a couple of people asked about adding inline code into an aspx page, that resides in a page library or document library. This is an interesting problem that could introduce some security concerns. Let's step back and look at how SharePoint works with aspx that resides on the database.

SharePoint has the ability to provision and customize pages within a site without the need to make any changes to the local file system of the front-end Web server. This capability of SharePoint is made possible by storing customized versions of .aspx files and .master files inside the content database and retrieving them on demand when they are needed to process an incoming page request. SharePoint uses a component called Virtual Path Provider (which is introduced in ASP.NET 2.0) to execute the pages from the content database.

The idea behind a virtual path provider is that it abstracts the details of where page files are stored away from the ASP.NET runtime. By creating a custom virtual path provider, a developer can write a custom component that retrieves ASP.NET file types, such as .aspx and .master files, from a remote location, such as a Microsoft SQL Server database. Once a virtual path provider retrieves the contents of an .aspx page, it can pass it along to the ASP.NET runtime for parsing.

The Windows SharePoint Services team created a virtual path provider named SPVirtualPathProvider that is integrated into every Web application. The SPVirtualPathProvider class is integrated into the ASP.NET request handling infrastructure by the SPRequestModule. More specifically, the SPRequestModule component contains code to register the SPVirtualPathProvider class with the ASP.NET Framework as it does its work to initialize a Web application. The SPVirtualPathProvider retrieves an ASP.NET page file from the content database, such as default.aspx, and then passes it along to the ASP.NET page parser. The SPVirtualPathProvider class works together with another class named the SPPageParserFilter to supply processing instructions to the ASP.NET page parser.You could read more details from the MSDN article SharePoint Architecture.

From the architecture of SharePoint Page execution model we could conclude that it is possible to run inline code from an ASP.Net page even if it resides on the content database. Let us go through the steps to make an aps page working.

Define PageParserPath in Apllication web.config

The first step is to set the PageParserPath in SharePoint web application's Web.config file. For example my SharePoint web application running on port 80 and it is mapped to the physical directory "c:\inetpub\wwwroot\wss\80", then go to the physical folder and open the file and search for the page parser path that exists under the SafeMode Section like in the following
. In the PageParserPath element, set the virtual path to the relative path of the Page library or document library in which we will be keeping the aspx page with inline code.

<SharePoint>
 
<SafeMode ... >
   
<PageParserPaths>
     
<PageParserPath 
          
VirtualPath="/sites/TestInline/Pages/*
         
CompilationMode="Auto
         
AllowServerSideScript="true" />
   
</PageParserPaths>
 
</SafeMode>
</SharePoint>

You need to set AlowServerSideScript and IncludeSubFolders and Comiplation Mode.

The possible values of Compilation Mode are:

  • Always: The default value, which compiles the page always
  • Auto: Page will not be compiled if possible
  • Never: The page will not be dynamically compiled

Create an aspx page

Create the aspx page that you want to have inline code, something like the following
. You could add a proper master page so it will maintain the UI consistency of your site.

<%@ Import Namespace="System" %>
 <%@ Page Language="c#"%>
 
<script runat="server">
   public string ServerSideFunction()
   {
     return "Hello I Am Your Inline Experiment";
   }
 </script> 
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
 <title>ASP.NET inline</title>
 </head>
 <body>
 <% =ServerSideFunction() %>
 </body>
 </html
>

Add aspx Page to Document or Page Library

The final step is upload the aspx page into the document or page library so that it will go to the content database. Once you have uploaded you could browse to the aspx page and verify that it is working.
Example: Let assume I have a SharePoint Root site (http://MyServer/Sites) and created a subsite (http://MyServer/Sites/TestInline ) called TestInline under it. Then I created a page library called pages in the TestInline site for keeping all my inline code APS pages. In order to do that I added the PageParser element into my web.config with a virtualpath of "/sites/TestInline/Pages/*". In the final step I created a test.aspx and uploaded it to my page library and accessed the page "http://MyServer/Sites/TestInline/Test.aspx".

Important Points needs to be considered

  1. Performance

    The PageParserPath directive is used in combination with the three properties CompilationMode="Always", AllowServerSideScript="true" and IncludeSubFolders="true". Each page in the folders specified in the VirtualPath attribute will be compiled into "C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\" as an App_Web_GUID.dll file. When you edit the aspx page in SharePoint, the file's last modified date will change and ASP.Net will recompile the page. ASP.Net will restart the application domain after 15 recompilations that will unload all DLLs from memory and run garbage collection and release all cached resources. The next request will initialize a new application domain for the web site and start compiling pages and repopulate caches, therefore the request will take more time.

    In order to increase the recompilation limit the numRecompilesBeforeAppRestart must be added or edited in the compilation element, for example:

    <compilation debug="false" numRecompilesBeforeAppRestart="50" />

    Compilation Element (ASP.NET Settings Schema)

    http://msdn.microsoft.com/en-US/library/s10awwz0(v=VS.90).aspx
     
  2. Security

    This could introduce security issues to the site, so we need to properly control who can upload inline code aspx pages to the designated library. Otherwise this could lead to security vulnerability in the system.