Create an administration page on SharePoint 2010

I have created my first page on the SharePoint central administration.

This example simply lists the sites of a selected site collection and also lets to select some of them. It’s completely useless but it explains how to create your administration page and to use a persistent object to save the selected sites.

First of all create a new ‘Empty SharePoint Project’

Choose your central administration site to debug, validate and finish.

Your solution explorer has to seem like this one:

To begin create a persistant object to save the sites selected by the administrator.

The class ‘Persistant’ inherits from ‘SPPersistedObject’, has an persisted object tagged with [Persisted] tag and constructors.

public class PersistedSettings : SPPersistedObject
    { 
            [Persisted] 
            public List<Guid> SiteCollectionsEnabled = new List<Guid>(); 
            public PersistedSettings() { } 
            public PersistedSettings(string name, SPPersistedObject parent, Guid id) 
                : base(name, parent, id) 
            { 
            } 
    }

Add new ‘SharePoint Mapped’ folder called ‘ADMIN’. This will contain our ASPX administration page.

This page is an ‘Application Page’

This new page is put in a new ‘Layouts’ folder. Move it to the ‘ADMIN’ folder and delete the ‘Layouts’ one.

We will create a page as the following one:

There is three important parts:

  • ‘InputFormSection’ and ‘ButtonSection’ are used SharePoint-pages. It’s to use the SharePoint layout easily and you just have to add your controls in. Please go to Karine Bosch’s post for more explanations about these controls.
  • ‘SharePoint:WebApplicationSelector’ is a control useful to select the site collection.
  • ‘ASP:Repeater’ is used to list the site list of the selected site collection.
<%@ Register TagPrefix="wssuc" TagName="InputFormSection" Src="/_controltemplates/InputFormSection.ascx" %> 
<%@ Register TagPrefix="wssuc" TagName="ButtonSection" Src="/_controltemplates/ButtonSection.ascx" %> 
<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
</asp:Content>
<asp:Content ID="PageDescription" ContentPlaceHolderID="PlaceHolderPageDescription" runat="server">
  This page allows you to display the site list of a site collection. 
</asp:Content>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<table width="100%" class="propertysheet" cellpadding="0" cellspacing="0" border="0">
    <tr><td class="ms-error"><asp:Literal ID="ErrorMessageLiteral" runat="server" EnableViewState="false" /> </td></tr>
  </table>
  <table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tr>
      <td>
        <!-- web application selector -->
        <wssuc:InputFormSection runat="server"
                    Title="<%$Resources:spadmin, multipages_webapplication_title%>"
                    Description="<%$Resources:spadmin, multipages_webapplication_desc%>" >
          <Template_InputFormControls>
            <tr>
              <td>
                <SharePoint:WebApplicationSelector id="WebAppSelector" runat="server"  
                  OnContextChange="WebAppSelector_OnContextChange" />
              </td>
            </tr>
          </Template_InputFormControls>
        </wssuc:InputFormSection>
        <!-- site collection selector -->
        <wssuc:InputFormSection runat="server"
                                  Title="Site Collections"
                                  Description="Select the site collections to enable or disable the warmup job. Only the top level site's homepage within the site collection is hit.">
          <Template_InputFormControls>
            <tr valign="top">
              <td>
                <asp:Repeater ID="SiteCollectionRepeater" runat="server"  
                OnItemDataBound="SiteCollectionRepeater_OnItemDataBound">
                  <ItemTemplate>
                    <asp:TextBox runat="server" Visible="false" ID="SiteCollectionIdTextBox" />
                    <asp:CheckBox ID="Checked" runat="server" class="ms-descriptionText" RepeatDirection="Horizontal" />
                    <asp:Literal runat="server" ID="SiteCollectionLiteral" /><br />                  
                  </ItemTemplate>
                  <SeparatorTemplate><br /></SeparatorTemplate>
                </asp:Repeater>
              </td>
            </tr>
          </Template_InputFormControls>
        </wssuc:InputFormSection>
        <wssuc:ButtonSection runat="server">
          <template_buttons>
            <asp:Button id="SaveButton" runat="server" class="ms-ButtonHeightWidth" Text="OK"  
            OnClick="SaveButton_OnClick" />
          </template_buttons>
        </wssuc:ButtonSection>
      </td>
    </tr>
  </table>
</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
Site List By Site Collection 
</asp:Content>
<asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
Site List By Site Collection 
</asp:Content>

This is the code behind. There is three principal event:

  • WebAppSelector_OnContextChange: to get the site collection complete list.
  • SiteCollectionRepeater_OnItemDataBound : to retrieve the site of the selected site collection and check wich one are selected
  • SaveButton_OnClick : to save the new list of selected sites.
public partial class SiteListBySiteCollectionPage : LayoutsPageBase
    { 
        protected Literal ErrorMessageLiteral; 
        protected WebApplicationSelector WebAppSelector; 
        protected Repeater SiteCollectionRepeater; 
        protected void Page_Load(object sender, EventArgs e) 
        { 
            SPContext.Current.Web.AllowUnsafeUpdates = true; 
        } 
        protected void WebAppSelector_OnContextChange(object sender, EventArgs e) 
        { 
            InitSiteCollectionSelector(); 
        } 
        private void InitSiteCollectionSelector() 
        { 
            if (this.WebAppSelector.CurrentItem.Sites.Count > 0) 
            { 
                this.SiteCollectionRepeater.DataSource = this.WebAppSelector.CurrentItem.Sites; 
                this.SiteCollectionRepeater.DataBind(); 
            } 
        } 
        protected void SiteCollectionRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e) 
        { 
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
            { 
                SPSite siteCollection = e.Item.DataItem as SPSite; 
                TextBox siteCollectionIdTextBox = e.Item.FindControl("SiteCollectionIdTextBox"as TextBox; 
                siteCollectionIdTextBox.Text = siteCollection.ID.ToString(); 
                Literal siteCollectionName = e.Item.FindControl("SiteCollectionLiteral"as Literal; 
                siteCollectionName.Text = siteCollection.Url; 
                CheckBox checkbox = e.Item.FindControl("Checked"as CheckBox; 
                if (SiteCollectionHasWarmupJobConfigured(siteCollection)) 
                    checkbox.Checked = true; 
                else
                    checkbox.Checked = false; 
            } 
        } 
        private bool SiteCollectionHasWarmupJobConfigured(SPSite siteCollection) 
        { 
            try
            { 
                PersistedSettings settings = this.WebAppSelector.CurrentItem.GetChild<PersistedSettings>("SiteListSelected"); 
                // If no settings previously created, create them now.
                if (settings == null) 
                { 
                    SPPersistedObject parent = this.WebAppSelector.CurrentItem; 
                    settings = new PersistedSettings("SiteListSelected", parent, Guid.NewGuid()); 
                    settings.Update(); 
                } 
                return settings.SiteCollectionsEnabled.Contains(siteCollection.ID);                           } 
            catch (Exception ex) 
            { 
                ErrorMessageLiteral.Text = ex.Message + "A new storage location had to be created. Please go back to the Application Management page and come back in before doing any work."; 
                return false; 
            } 
        } 
        protected void SaveButton_OnClick(object sender, EventArgs e) 
        { 
            PersistedSettings settings = this.WebAppSelector.CurrentItem.GetChild<PersistedSettings>("SiteListSelected"); 
            // Purge the configuration data for the current Web application.
            settings.SiteCollectionsEnabled.Clear(); 
            settings.Update(); 
            // Get a list of all the site collections that were requested to be enabled.
            List<Guid> selectedSiteCollections = GetSelectedSiteCollections(); 
            if (selectedSiteCollections.Count > 0) 
            { 
                // Add the settings.
                foreach (Guid siteCollectionID in selectedSiteCollections) 
                { 
                    settings.SiteCollectionsEnabled.Add(siteCollectionID); 
                } 
                settings.Update(); 
            } 
        } 
        private List<Guid> GetSelectedSiteCollections() 
        { 
            List<Guid> selectedSiteCollections = new List<Guid>(); 
            TextBox siteCollectionIdTextBox; 
            CheckBox chk; 
            foreach (RepeaterItem item in SiteCollectionRepeater.Items) 
            { 
                siteCollectionIdTextBox = item.FindControl("SiteCollectionIdTextBox"as TextBox; 
                chk = item.FindControl("Checked"as CheckBox; 
                if (chk.Checked) 
                    selectedSiteCollections.Add(new Guid(siteCollectionIdTextBox.Text)); 
            } 
            return selectedSiteCollections; 
        } 
    } 

The page is created and now we just have to deploy it as a new feature. For this, add a new module:

And add this code:

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction Id="04B5F622-AF31-481A-891D-0032B72F84DA" GroupId="SiteCollections" 
      Location="Microsoft.SharePoint.Administration.Applications" 
      Sequence="20" RequiredAdmin="Delegated" 
      Title="Site List" Description="">
    <UrlAction Url="_admin/SiteListBySiteCollection/SiteListBySiteCollectionPage.aspx" />
  </CustomAction>
</Elements>

It says that the page link will be on the ‘Microsoft.SharePoint.Administration.Applications’ page under the ‘SiteCollections’ section. Get all the custom actions available here.

To finish, add a new feature and add the module in.

Your solution explorer has to seem like this one right now:

You can deploy your solution.

And visit the central administration to see the link as expected.

One the page and you can choose a site collection and list and check its sites.