SharePoint 2007 - /_layouts and how to create pages that run in site context
Ages ago, in the time that SharePoint 2007 was still beta, I dived into how to create "in site context" pages that should be hosted in the /_layouts directory of SharePoint. My adventures from back then can be found in this blog post. I don't want to take the default Microsoft approach where all server-side code is included in the aspx pages themselves. Developing this way is way more difficult that using code-behind files. I found a solution by creating a Visual Studio 2005 web site in the /_layouts virtual directory of my SharePoint web site, which points to the physical folder C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS. In this approach all code behind files are part of the solution, and are compiled and cached on page request. Although this approach works, I don't really like it. I prefer the Visual Studio 2003 approach where all code-behind is compiled into a single assembly that can be deployed. Another problem is the location of referenced assemblies. I had my referenced assemblies in the GAC, but I prefer to deploy to a bin folder so no IISRESET recycling of the SharePoint application pool is needed on recompilation.
What I really want to achieve is the following:
Create a web application project that can be deployed to the SharePoint /_layouts virtual directory, so my code is executed in the context of a site.
The solution happens to be really easy:
Create a web application project, either directly in the /_layouts folder or somewhere else and copy over all files needed to run your application.
The *.dll and *.pdb files produced as build output must be places in the bin folder of your SharePoint web site. In my test situation this is the folder C:\Inetpub\wwwroot\wss\VirtualDirectories\3a938f6a-15f2-49ae-be78-328ad78974f5\bin. You can find this folder in your Internet Information Server Manager as follows:
- Right-click of the SharePoint web site
- Select properties
- Go to the Home Directory tab
The value in Local Path specifies the path to the virtual directory, and in this virtual directory you find a folder bin.
If you create your web application project within the /_layouts virtual directory, you can set the build output path directly to this bin folder.
Note that you can't use the Publish Web feature of the web application project, because you can't specify a separate path to deploy your assemblies to:
For my test I created the following project:
I added some really simple code to the Default.aspx and Default.aspx.cs files to prove that it works:
Default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SergeLayoutsTest._Default" %><!
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" > <head runat="server"> <title>Site title test</title> </head> <body> <form id="form1" runat="server"> <div> Title of this site: <asp:Label ID="LabelTitle" runat="server" Text="Label"></asp:Label> </div> </form> </body> </html>
Default.aspx.cs:
using System; using Microsoft.SharePoint;namespace SergeLayoutsTest { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { SPWeb web = SPContext.Current.Web; LabelTitle.Text = web.Title; } } }
There is one more thing to do, exclude the selection of the authentication mode from your web.config file:
web.config:
<?xml version="1.0"?><
configuration> <appSettings/> <connectionStrings/> <system.web> <compilation debug="true" /> <!-- <authentication mode="Windows" /> --> </system.web> </configuration>
We can now run the page in the context of two different sites to see that it works: