Thursday, December 22, 2011

Creating Custom Application Pages

Application pages such as Hello.aspx, ApplicationPage1.aspx, ApplicationPage2.aspx, and ApplicationPage3.aspx. This Visual Studio project also has a post-build event that runs a batch file named install.bat, which copies the application pages to where they need to be deployed inside the \LAYOUTS directory. The install.bat file also installs a feature named CustomApplicationPages, which adds menu items to the Site Actions menu of the current site and allows users to navigate the project’s application pages.
Once you open the CustomApplicationPages project, you should build it. This will run the install.bat file. After that point, you should be able to go to any site and activate the site-level feature named CustomApplicationPages, which will then allow you to follow along with the examples throughout the remainder of this chapter.
Notice that while it is possible to deploy your application pages directly inside the \LAYOUTS directory, this can cause problems due to potential file name conflicts between your application pages and those created by Microsoft and other companies. It is a best practice to deploy your application pages inside a company-specific or project-specific directory that is nested within the \LAYOUTS directory. The application pages in the sample project discussed here are deployed within a project-specific directory located at the path \LAYOUTS\CustomApplicationPages.
As a rule, application pages should derive from a base class in the Microsoft.SharePoint assembly named LayoutsPageBase. For example, assume that you want to create a custom application page to display some information about the current site. In our first example, we will work with an application page named Hello.aspx, which does exactly that.
Application pages are usually created as content pages that link to the master page named application.master that resides in the \LAYOUTS directory. This master page file can be referenced in a custom application page using a virtual path of ~/_layouts/application.master. The definition for the application page named Hello.aspx shown in Listing 2-1 shows the starting point for creating your own application pages

Listing 2-1. A custom application page can contain HTML layout and in-line code

<%@ Assembly Name="Microsoft.SharePoint, [full 4-part assembly name]"%>  
<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master"  
         Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase"  %> 

<%@ Import Namespace="Microsoft.SharePoint" %> 

<script runat="server"> 
  protected override void OnLoad(EventArgs e) { 
    SPWeb site = this.Web; 
    lblSiteTitle.Text = site.Title; 
    lblSiteID.Text = site.ID.ToString().ToUpper(); 
  } 
</script> 

<asp:Content ID="Main" contentplaceholderid="PlaceHolderMain" runat="server"> 
  <table border="1" cellpadding="4" cellspacing="0" style="font-size:12"> 
    <tr> 
      <td>Site Title:</td> 
      <td><asp:Label ID="lblSiteTitle" runat="server" /></td> 
    </tr> 
    <tr> 
      <td>Site ID:</td> 
      <td><asp:Label ID="lblSiteID" runat="server" /></td> 
    </tr> 
  </table>        
</asp:Content> 

<asp:Content ID="PageTitle" runat="server" 
  contentplaceholderid="PlaceHolderPageTitle" > 
  Hello World 
</asp:Content> 

<asp:Content ID="PageTitleInTitleArea" runat="server" 
  contentplaceholderid="PlaceHolderPageTitleInTitleArea" > 
  The Quintessential 'Hello World' Application Page 
</asp:Content>
Notice that the application page example shown in Listing 2-1 adds three Content tags to add HTML content to the resulting page. In particular, this page replaces placeholders defined inside application.master named PlaceHolderMain, PlaceHolderPageTitle, and PlaceHolderPageTitleInTitleArea. However, these are just three of the many different placeholders defined inside application.master that you can choose to replace.
Also notice that the version of Hello.aspx shown in Listing 2-1 has a script block at the top containing code that programs against the Windows SharePoint Services object model. When you are programming a page like this within Visual Studio 2005, you are able to benefit from conveniences such as color-coding and IntelliSense. However, you must be sure to add the correct @Assembly directive to the top of the page. You should modify the @Assembly directive shown in Listing 2-1 with the assembly information for the Microsoft.SharePoint assembly shown here.
 
Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C

We have added line breaks here to make this information more readable. However, you should make sure that you add all of the assembly information in a single line whenever you add an @Assembly directive to an .aspx file.
Application pages are handy because they provide quick and easy access to the Windows SharePoint Services object. Once you have created an application page and provided an overridden implementation of the OnLoad method, as shown in Listing 2-1, you can obtain entry points into the Windows SharePoint Services object model in a site-specific context using the following code, which uses properties exposed by underlying LayoutsPageBase base class.


Now that you have seen how to create an application page, let's complement it by adding a feature that adds a menu item to the Site Actions menu. This menu item will be created to allow the user to navigate to ApplicationPage1.aspx. In the last chapter, we demonstrated a technique for creating a custom feature with a CustomAction element. We will now create another CustomAction with a slight variation. Take a look at the following CustomAction element

<CustomAction Id="SiteActionsToolbar"
  GroupId="SiteActions"
  Location="Microsoft.SharePoint.StandardMenu"
  Sequence="2001"
  Title="Application Page 1"
  Description="Check out some typical site properties"
  ImageUrl="/_layouts/images/DECISION.GIF">
    <UrlAction Url="~site/_layouts/CustomApplicationPages/ApplicationPage1.aspx"/>
</CustomAction>


Adding a Custom Menu Item to the ECB Menu

We will now take the idea of creating a custom application page even further by examining one that displays information about a particular document in a document library. In our example, we will look at the application page named ApplicationPage4.aspx. We begin by creating a new CustomAction element. However, this CustomAction element does not add a menu item in the Site Actions menu. Instead, it is designed to add a new menu item to the ECB menu for each document within a document library. Examine the following XML fragment that defines a CustomAction

<CustomAction Id="ApplicationPage4.ECBItemMenu"
  RegistrationType="List" 
  RegistrationId="101"
  ImageUrl="/_layouts/images/GORTL.GIF"
  Location="EditControlBlock"
  Sequence="105"
  Title="Application Page 4" >

  <UrlAction Url="~site/_layouts/CustomApplicationPages/ApplicationPage4.aspx  
                  ?ItemId={ItemId}&amp;ListId={ListId}"
    />
</CustomAction>

This CustomAction element is different than what you have seen before because it has a RegistrationType attribute that is assigned a value of List. It also is configured with a RegstrationID attribute that is assigned a value of 101. Notice that 101 is a list type identifier that applies to all document libraries. You should also notice that the Location attribute has a value of EditControlBlock, which creates the effect of adding the menu item to the ECB menu of documents within a document library
If you look at the CustomAction element in this example, you see that the ActionUrl element is configured with a URL attribute that points to ApplicationPage4.aspx and appends the following QueryString
 
../ApplicationPage4.aspx?ItemId={ItemId}&amp;ListId={ListId}
// Get current site and web 
SPSite siteCollection = this.Site; 
SPWeb site = this.Web; 

// Access current list or document library 
string ListId = Request.QueryString["ListId"]; 
SPList list = site.Lists[new Guid(ListId)]; 

// Access current list item or document 
string ItemId = Request.QueryString["ItemId"]; 
SPListItem item = list.Items.GetItemById(Convert.ToInt32(ItemId));
 
In cases such as this one, you can assume that you are dealing with a 
document library and not simply a standard list type. In these situations, you can add code that converts the 
SPList object into a SPDocumentLibrary object. You can also access the 
document in question directly by creating an SPFile object as shown 
in the following sample
 
// Get current site and web 
SPSite siteCollection = this.Site; 
SPWeb site = this.Web; 

// Access current list or document library 
string ListId = Request.QueryString["ListId"]; 
SPList list = site.Lists[new Guid(ListId)]; 
lblListTile.Text = list.Title; 
lblRootFolderUrl.Text = list.RootFolder.Url; 

// If current list is a document library... 
SPDocumentLibrary documentLibrary = (SPDocumentLibrary)list; 
lblDocumentTemplateUrl.Text = documentLibrary.DocumentTemplateUrl; 

// Access current list item or document 
string ItemId = Request.QueryString["ItemId"]; 
lblDocumentID.Text = ItemId; 
SPListItem item = list.Items.GetItemById(Convert.ToInt32(ItemId)); 
lblDocumentName.Text = item.Name; 
lblDocumentUrl.Text = item.Url; 

// If current list is a document library... 
SPFile file = site.GetFile(item.Url); 
lblFileAuthor.Text = file.Author.Name; 
lblFileSize.Text = file.TotalLength.ToString("0,###") + " bits"; 
lblFileLastModified.Text = "By " + file.ModifiedBy.Name + 
                           " on " + file.TimeLastModified.ToLocalTime().ToString(); 
lblFileCheckOutStatus.Text = file.CheckOutStatus.ToString();
 

No comments:

Post a Comment