Similar to working with ASP.NET 2.0 Web sites, you are free to create new pages within Windows SharePoint Services sites, including site and application pages, and those that are subject to the same customization rules outlined earlier. You can create pages in one of two ways: either by using the Windows SharePoint Services API, or by provisioning uncustomized instances using SharePoint Features. The following sections cover these two approaches and the advantages and disadvantages of both.
One available option for creating custom pages in SharePoint sites is to use the Windows SharePoint Services API. This approach includes creating pages by using tools such as SharePoint Designer. SharePoint Designer interacts with SharePoint sites through the API by using RPC calls and Web services. Because these pages are created using the API, they live exclusively in the content database and thus are considered customized files.
Creating pages directly by using the API involves creating a new file as a memory stream. After you create the contents of the file, you create the file in the SharePoint site by calling the Add method on the Files collection of the site, as shown in the following code.
using (SPSite siteCollection = new SPSite("http://litware.com")) {
using (SPWeb site = siteCollection.RootWeb) {
MemoryStream fileStream = new MemoryStream();
StreamWriter fileWriter = new StreamWriter(fileStream);
// Write the source of the page (include meta:progid so SharePoint Designer understands this file).
fileWriter.WriteLine("<%@ Page MasterPageFile=\"~masterurl/default.master\"
meta:progid=\"SharePoint.WebPartPage.Document\" %>");
fileWriter.WriteLine("<asp:Content runat=\"server\" ContentPlaceHolderID=\"PlaceHolderMain\">");
fileWriter.WriteLine("<h1>MSDN</h1>");
fileWriter.WriteLine("</asp:Content>");
fileWriter.Flush();
// Save the file to Windows SharePoint Services.
site.Files.Add("ApiGeneragedPage.aspx", fileStream);
// Cleanup.
fileWriter.Close();
fileWriter.Dispose();
fileStream.Close();
fileWriter.Dispose();
} // SPWeb using statement
} // SPSite using statement
Creating files by using SharePoint Designer essentially does the same thing. SharePoint Designer streams the new content directly into the site through the API, as shown in the previous code example.
To create a new page in a SharePoint site by using SharePoint Designer, click New on the File menu, and then select the type of file to create.
Advantages of Creating Customized Pages
Creating pages by using the SharePoint API, including in SharePoint Designer, has many advantages. First, there are plenty of resources available in creating new pages available in the form of white papers, articles, documentations, and other various formats. In addition, creating new pages by using a tool such as SharePoint Designer make it very simple because of its familiar what-you-see-is-what-you-get (WYSIWYG) environment. Finally, it is very easy to make quick changes to pages in an environment by using tools such as SharePoint Designer.
Disadvantages of Creating Customized Pages
As with most things, there is not only an upside but also a downside to creating customized pages. First, after you create a page in one environment, it is not very easy to move that page to another environment because it resides exclusively in the site collection's content database; it is not as easy as exporting and importing the page. So how can you move a page from one environment to another? The obvious approach is to manually re-create it. Another option is to create a script that can extract the contents of an existing page and create a copy in a target environment. Although these are both possible options, they raise additional concerns when you are maintaining changes to pages.
Another challenge is that you cannot easily incorporate these pages into a source control management solution such as Microsoft Visual Studio Team Foundation Server.
Instead of creating customized pages, you can also create page templates and a SharePoint Feature that would in turn create a new uncustomized instance of the page within a SharePoint site. This approach enables developers to stay within the bounds of the Microsoft Visual Studio environment. Unfortunately, some things that you might be used to when you create ASP.NET 2.0 Web sites do not work when you are creating pages for SharePoint sites. In these cases, you should take a step back and think about what Visual Studio is doing in a pure ASP.NET 2.0 environment.
A common example of this is debugging because many people think that debugging custom code is not possible in Windows SharePoint Services. Consider what happens in a pure ASP.NET 2.0 environment. Visual Studio compiles the project, starts a new Web process that requests the page, and attaches the Visual Studio debugger to the process. At this point, breakpoints that are set by the debugger can be hit, variables can be inspected, and so on. But when you are developing Windows SharePoint Services pages, pressing F5 does not work—but why? It is because Visual Studio has no native hooks into the Windows SharePoint Services environment. This does not mean that debugging is impossible when you are creating Windows SharePoint Services pages; it just means that some manual work is necessary. A developer would compile the project, fire off the Web process requesting the page in question, and manually attach the debugger.
To create uncustomized pages, you must first create a page template (the ASPX file) that can optionally use a code-behind file and the SharePoint Feature that will provision the uncustomized instance of the page based on the template upon activation. First create the page template as follows.
<%@ Page Language="C#" MasterPageFile="~masterurl/default.master"
meta:progid="SharePoint.WebPartPage.Document" %>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderMain">
<h1>MSDN</h1>
Custom page creates as an uncustomized instance.
</asp:Content>
With the ASPX page created, the next step is to create the Feature. First, the Feature definition is quite straightforward, as shown in this example.
<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
Id="597D8309-C964-48ef-8D24-D5C60C94A832"
Title="MSDN Uncustomized Page Feature"
Scope="Web">
<ElementManifests>
<ElementManifest Location="elements.xml"/>
<ElementFile Location="PageTemplate.aspx" />
</ElementManifests>
</Feature>
Finally, create the element manifest file that provisions the uncustomized instance of the page into the SharePoint site as follows.
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Url="SamplePages">
<File Url="PageTemplate.aspx" Name="SamplePage.aspx" Type="Ghostable" />
</Module>
</Elements>
After the Feature has been installed and activated, a new uncustomized instance of the page is provisioned into the target site. You open this page in tools such as SharePoint Designer and customize it just like any other page; it is no different from, for example, the default.aspx page found at the root of all SharePoint sites.
Advantages of Creating Uncustomized Pages
Creating uncustomized pages has many advantages over creating customized ones. First, keeping the files uncustomized on the server makes it much easier to update many files between various environments because the source of the files is always being pulled from the file on the file system. In addition, because Features are used as the vehicle for adding these files to the site, you can use Windows SharePoint Services solution packages (WSP files) to package many files for deployment from one environment to another. This includes existing files that must be updated. Because these files are uncustomized, updating the files on the file system changes the page itself.
Another advantage to this approach is that the source of the files stays on the file system, and they can easily be added to any source control management solution because all understand files on the file system. This approach also makes it much easier for organizations with a strict change control process to implement changes across environments because it an easily repeatable process.
Disadvantages of Creating Uncustomized Pages
Just like creating customized pages, creating uncustomized pages also has its disadvantages. As shown earlier, not only do you have to create the actual page template, but you also have to create the Feature that handles the provisioning of the page. Unfortunately, this results in double development. In addition, Features are tedious to build because they require knowledge of Collaborative Application Markup Language (CAML), and they provide minimal debugging support when things go wrong.
Another disadvantage to this approach is that the Feature that provisions the instances does not remove the instances upon deactivation. This is by design, but you can easily lessen the effects by using a custom Feature receiver that deletes the created files when the feature is deactivated.