SharePoint: Creating Custom Administration Pages


In this post we are going to create a custom Administration Page and deploy it into the Application Management section of the Central Administration site.

Central Administration - Application Management
Central Administration - Application Management

An administration page such as this is classed as a SharePoint application page and developing a custom administration page differs only slightly from developing a custom application page which you might deploy at a site collection or web level, such as the Site Content Types page (mngctype.aspx).

Manage Site Content Types
Manage Site Content Types

The main components we will develop are;

Administration page ASPX

Contains the markup for the page user interface

Administration page code-behind

Contains the  page business logic, processing and event handler code

Deployment Feature

A Farm scoped feature which creates a custom action group and custom action in the Application Management page of the Central Administration site.

The custom action links the user to the administration page.

Getting Started

First add a reference to the Microsoft.SharePoint.ApplicationPages.Administration.dll assembly which can be found in the 12 hive at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\CONFIG\ADMINBIN.

Next create a new public C# class which derives from GlobalAdminPageBase in the Microsoft.SharePoint.ApplicationPages namespace, this class will be the ASPX page’s code-behind class.

using System;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.ApplicationPages;
using Microsoft.SharePoint.WebControls;

namespace Test.Administration.Page.SharePoint.Definitions.ApplicationPages
{
	public class mytestadministrationpage : GlobalAdminPageBase
	{}

Having created your class, note down or find it using reflector, the fully qualified type name, in my case it is;

Test.Administration.Page.SharePoint.Definitions.ApplicationPages.mytestadministrationpage, Test.Administration.Page, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9960cf7ddc263f39

Creating the Administration page ASPX

For more information on SharePoint Central Administration pages, see this article in MSDN.

In your solution add a new text file, and rename it as an ASPX file, e.g. mytestadministrationpage.aspx.

Add the markup required to create the administration page user interface, the markup below shows a simple administration page with  WebApplicationSelector and InputFormTextBox controls.

<%@ Page Language="C#"
			MasterPageFile="~/_admin/admin.master"
			Inherits="Test.Administration.Page.SharePoint.Definitions.ApplicationPages.mytestadministrationpage, Test.Administration.Page, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9960cf7ddc263f39"
			AutoEventWireup="true" %>

<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="wssawc" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Register TagPrefix="wssuc" TagName="ToolBar" src="~/_controltemplates/ToolBar.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="InputFormSection" src="~/_controltemplates/InputFormSection.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="InputFormControl" src="~/_controltemplates/InputFormControl.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ButtonSection" src="~/_controltemplates/ButtonSection.ascx" %>

<asp:Content ID="Content1" contentplaceholderid="PlaceHolderPageTitle" runat="server">
    My Test Administration Page
</asp:Content>

<asp:Content ID="Content2" contentplaceholderid="PlaceHolderPageTitleInTitleArea" runat="server">
    My Test Administration Page
</asp:Content>

<asp:content ID="Content3" contentplaceholderid="PlaceHolderPageDescription" runat="server">
    Manage configuration settings which are scoped at the web Application level.
</asp:content>

<asp:content ID="Content4" contentplaceholderid="PlaceHolderMain" runat="server">
<asp:Panel ID="inputControls" runat="server">
    <table border="0" cellspacing="0" cellpadding="0" width="100%">
        <tr>
          <td width="50%">
            <!-- **************************************
                 use sharepoint buttonsection control
                 to display the "ok" and "cancel" buttons -->
            <wssuc:ButtonSection runat="server" TopButtons="true"
                BottomSpacing="5" ShowSectionLine="false" ShowStandardCancelButton="false">
                <Template_Buttons>
                    <asp:Button UseSubmitBehavior="false" runat="server"
                        class="ms-ButtonHeightWidth"
                        Text="<%$Resources:wss,multipages_okbutton_text%>"
                        id="btnSubmitTop" ToolTip="Save current settings"
                        accesskey="<%$Resources:wss,okbutton_accesskey%>"
                        Enabled="true"/>
                    <asp:Button UseSubmitBehavior="false" runat="server"
                        class="ms-ButtonHeightWidth"
                        Text="<%$Resources:wss,multipages_cancelbutton_text%>"
                        CausesValidation="False"
                        id="btnCancelTop"
                        CommandName="Cancel"
                        accesskey="<%$Resources:wss,multipages_cancelbutton_accesskey%>"
                        Enabled="true"/>
                </Template_Buttons>
            </wssuc:ButtonSection>
            <!-- ************************************** -->

            <!-- **************************************
                 display the web application selector
                 using the inputformsecton and
                 webapplicationselector controls -->
            <wssuc:InputFormSection runat="server"
                Title="Web Application"
                Description="Select a Web Application" >
                <Template_InputFormControls>
                <tr>
                    <td>
                    <SharePoint:WebApplicationSelector id="WebAppSelector" runat="server"
						  			TypeLabelCssClass="ms-listheaderlabel"
						  			HoverCellActiveCssClass = "ms-viewselectorhover"
									HoverCellInActiveCssClass = "ms-viewselector" /><br />
							<span style="padding-left:6px;"><asp:Literal ID="litWebAppName" runat="server" /></span>
                    </td>
                </tr>
                </Template_InputFormControls>
            </wssuc:InputFormSection>
           <!-- *************************************** -->

           <!-- ***************************************
                display an input form section -->
           <wssuc:InputFormSection runat="server"
                Title="Input Form Section"
                Description="An input form section description" >
                <Template_InputFormControls>
  			        <wssuc:InputFormControl runat="server"
				        LabelText="An Input Form Control">
				        <Template_Control>
					        <wssawc:InputFormTextBox Title="Configuration Site URL" class="ms-input" ID="txtConfigurationSiteURL" Columns="75" Runat="server" MaxLength=255 EnableViewState="true" />
					        <wssawc:InputFormRequiredFieldValidator
						        ID="ReqValtxtConfigurationSiteURL"
						        ControlToValidate="txtConfigurationSiteURL"
						        ErrorMessage="You must enter a valid URL!"
						        Runat="server"/>
				        </Template_Control>
			        </wssuc:InputFormControl>
                </Template_InputFormControls>
            </wssuc:InputFormSection>
            <!-- ************************************** -->

        </td>
       </tr>
    </table>
</asp:Panel>

<!-- Literal Control to display messages -->
<div style="font-size:12pt;color:red;font-weight:bold;"><asp:Literal ID="litMessages" runat="server" /></div>
</asp:content>

This displays the page shown below;

Simple Administration Page
Simple Administration Page

Of note in the ASPX markup is the Page directive;

<%@ Page Language="C#"
			MasterPageFile="~/_admin/admin.master"
			Inherits="Test.Administration.Page.SharePoint.Definitions.ApplicationPages.mytestadministrationpage, Test.Administration.Page, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9960cf7ddc263f39"
			AutoEventWireup="true" %>

The Inherits attribute is used to identify the page’s code-behind and is shown using the fully qualified type name.

The MasterPageFile attribute is set to use the Administration master page.

The AutoEventWireup attribute is set to true.

Next come the registered SharePoint assemblies and user controls;

<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="wssawc" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Register TagPrefix="wssuc" TagName="ToolBar" src="~/_controltemplates/ToolBar.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="InputFormSection" src="~/_controltemplates/InputFormSection.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="InputFormControl" src="~/_controltemplates/InputFormControl.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ButtonSection" src="~/_controltemplates/ButtonSection.ascx" %>

The WebApplicationSelectorControl control;

<wssuc:InputFormSection runat="server"
	 Title="Web Application"
	 Description="Select a Web Application" >
	 <Template_InputFormControls>
	 <tr>
		  <td>
		  <SharePoint:WebApplicationSelector id="WebAppSelector" runat="server"
					TypeLabelCssClass="ms-listheaderlabel"
					HoverCellActiveCssClass = "ms-viewselectorhover"
					HoverCellInActiveCssClass = "ms-viewselector" /><br />
			<span style="padding-left:6px;"><asp:Literal ID="litWebAppName" runat="server" /></span>
		  </td>
	 </tr>
	 </Template_InputFormControls>
</wssuc:InputFormSection>
Web Application Selector Control
Web Application Selector Control

The InputFormSectionInputFormControl and InputFormTextBox controls;

<wssuc:InputFormSection runat="server"
	 Title="Input Form Section"
	 Description="An input form section description" >
	 <Template_InputFormControls>
	  <wssuc:InputFormControl runat="server"
		  LabelText="An Input Form Control">
		  <Template_Control>
			  <wssawc:InputFormTextBox Title="Configuration Site URL" class="ms-input" ID="txtConfigurationSiteURL" Columns="75" Runat="server" MaxLength=255 EnableViewState="true" />
			  <wssawc:InputFormRequiredFieldValidator
				  ID="ReqValtxtConfigurationSiteURL"
				  ControlToValidate="txtConfigurationSiteURL"
				  ErrorMessage="You must enter a valid URL!"
				  Runat="server"/>
		  </Template_Control>
	  </wssuc:InputFormControl>
	 </Template_InputFormControls>
</wssuc:InputFormSection>
SharePoint Web Controls
SharePoint Web Controls

The Administration page code-behind

Next we’ll populate the code behind file, in this example we will react to the Context Changed event of the web application selector control.

using System;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.ApplicationPages;
using Microsoft.SharePoint.WebControls;

namespace Test.Administration.Page.SharePoint.Definitions.ApplicationPages
{
	/** Fully Qualified Type Name
	 Test.Administration.Page.SharePoint.Definitions.ApplicationPages.mytestadministrationpage, Test.Administration.Page, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9960cf7ddc263f39
	 */
	public class mytestadministrationpage : GlobalAdminPageBase
	{
		protected Panel inputControls;
		protected Button btnSubmitTop;
		protected Button btnCancelTop;
		protected WebApplicationSelector WebAppSelector;
		protected Literal litWebAppName;
		protected InputFormTextBox txtConfigurationSiteURL;
		protected Literal litMessages;

		protected void Page_Load(object sender, EventArgs e)
		{
			// wire-up control event handlers
			btnSubmitTop.Click += btnSubmitTop_Click;
			btnCancelTop.Click += btnCancelTop_Click;
			WebAppSelector.ContextChange += WebAppSelector_ContextChange;

			if (!IsPostBack)
			{
				// default value
				txtConfigurationSiteURL.Text = "n/a";
			}
		}

		void WebAppSelector_ContextChange(object sender, EventArgs e)
		{
			// user changed the web application selection
			// NOTE: this event also fire when the page first loads
			var wa = ((WebApplicationSelector)sender).CurrentItem;
			if (wa == null)
			{
				litWebAppName.Text = "n/a";
				txtConfigurationSiteURL.Text = "n/a";
				return;
			}

			litWebAppName.Text = string.Format("{0}", string.Format("{0}", wa.Name));
			txtConfigurationSiteURL.Text = wa.Sites.Count > 0
														? wa.Sites[0].Url
														: "n/a";
		}

		void btnCancelTop_Click(object sender, EventArgs e)
		{
			// go back to Application Management
			Response.Redirect("/_admin/applications.aspx");
		}

		void btnSubmitTop_Click(object sender, EventArgs e)
		{
			// save page values and go back to Application Management

			Response.Redirect("/_admin/applications.aspx");
		}
	}
}

In Page_Load, we hook up the control event handlers and set a default for the single text box control.

protected void Page_Load(object sender, EventArgs e)
{
	// wire-up control event handlers
	btnSubmitTop.Click += btnSubmitTop_Click;
	btnCancelTop.Click += btnCancelTop_Click;
	WebAppSelector.ContextChange += WebAppSelector_ContextChange;

	if (!IsPostBack)
	{
		// default value
		txtConfigurationSiteURL.Text = "n/a";
	}
}

In the web application selectors Context Changed event handler, we set a couple of controls to the value of the selected web application’s Name and Url properties.

void WebAppSelector_ContextChange(object sender, EventArgs e)
{
	// user changed the web application selection
	// NOTE: this event also fire when the page first loads
	var wa = ((WebApplicationSelector)sender).CurrentItem;
	if (wa == null)
	{
		litWebAppName.Text = "n/a";
		txtConfigurationSiteURL.Text = "n/a";
		return;
	}

	litWebAppName.Text = string.Format("{0}", string.Format("{0}", wa.Name));
	txtConfigurationSiteURL.Text = wa.Sites.Count > 0
												? wa.Sites[0].Url
												: "n/a";
}

Creating the Deployment Feature

Create a new feature, the feature should be a Farm scoped feature with an element manifest;

<Feature
		Id="B640853F-BF3D-47b9-A21A-7873B1EA4D75"
		Title="My Test Administration Page Feature"
		Description="Deploys the Test Administration Page into Central Administration."
		Version="12.0.0.0"
		Scope="Farm"
		xmlns="http://schemas.microsoft.com/sharepoint/"
		Hidden="FALSE"
		AlwaysForceInstall="TRUE"
    ActivateOnDefault="FALSE">
  <ElementManifests>
    <ElementManifest Location="elements.xml"/>
  </ElementManifests>
</Feature>

Create the element manifest file, elements.xml;

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomActionGroup
      Id="9E2760B9-C9AC-4785-BD39-E535B141B436"
      Location="Microsoft.SharePoint.Administration.ApplicationManagement"
      Title="My Administration Pages"
      Sequence="1001"/>
  <CustomAction
        Id="5A1FA71F-0FE7-4a21-BD4B-D98FFCFA1B96"
        GroupId="9E2760B9-C9AC-4785-BD39-E535B141B436"
        Location="Microsoft.SharePoint.Administration.ApplicationManagement"
        Sequence="50"
        Title="My Test Administration Page"
        Description="">
    <UrlAction Url="_admin/mytestadministrationpage.aspx"/>
  </CustomAction>
</Elements>

Inside the element manifest file we create a CustomActionGroup, give it a unique ID and associate it with the Application Management page.
We then create a new CustomAction, associate it with the custom action group (using the GroupId attribute) and give a unique ID, Title and associate it with the Application Management page using the Location attribute.

Deploy

Build and deploy the solution to your SharePoint farm. Restart IIS and then go to the  Central Administration site.

On the Operations page, click on the link to Manage Farm Features

Manage Farm Features
Manage Farm Features

The list of Farm Features displays, click on the link to activate our feature;

Farm Features
Farm Features

Navigate to Application Management, and you should see your new custom action group and custom action;

Application Management
Application Management

Click on the link to go to tour new administration page;

Custom Administration Page
Custom Administration Page

The project zip file for this solution can be found on my projects page.

Published by

Phil Harding

SharePoint Consultant, Developer, Father, Husband and Climber.

2 thoughts on “SharePoint: Creating Custom Administration Pages

  1. Do you know if I can create a way to logged changes that are made to the Site Collection Administrators via powershell and STSADM. Also, is there someway of preventing users from being able to use Powershell and STSADM to make changes to the Site Collection Admin and web application policy. In SharePoint 2010.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s