Monday, June 9, 2008

Site Pages versus Application Pages

Pages that support user customization are known as site pages. Every one of these site pages would become unghosted. This would negatively impact scalability by forcing the front-end Web server to retrieve each page separately from the content database. Each page would also have to be individually parsed and loaded into memory.

There is only one version of an application page scoped at the farm level, it can be
compiled into a single DLL and loaded into memory once for each Web application. You
never have to worry about the existence of different versions of an application page for different sites. Furthermore, application pages are not subject to attack from users who have permissions to customize site pages. Therefore, WSS does not prohibit them from containing in-line code.
There is only one version of an application page scoped at the farm level, it can be
compiled into a single DLL and loaded into memory once for each Web application.
Let us now summarize the difference between site pages and application pages. Site pages support page customization. Examples of site pages include the home page (default.aspx) for a site as well as the pages associated with lists and document libraries, such as AllItems.aspx, NewForm.aspx, and EditForm.aspx. The fact that site pages support customization provides flexibility but can also impact performance and scalability.Application pages do not support customization, which gives them two distinct advantages over site pages. First, each application page is always compiled into a single DLL so that it performs and scales better than a site page. Second, application pages are allowed to have in-line code.
Creating Custom Application Pages
As a rule, application pages should derive from a base class in the Microsoft.SharePoint assembly named LayoutsPageBase.

ApplicationPage1.aspx
%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" % >
%@ Assembly Name="CustomApplicationPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d4e5777b16a5749f" % >

%@ Page Language="C#" MasterPageFile="~/_layouts/application.master"
Inherits="CustomApplicationPages.ApplicationPage1"
EnableViewState="false" EnableViewStateMac="false" %>

asp:content id="Main" contentplaceholderid="PlaceHolderMain" runat="server">
table border="1" cellpadding="4" cellspacing="0" style="font-size:12">
tr>
td>Site Title:
td>
/tr>
tr>
td>Site ID:
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" >
Application Page 1: 'Hello World' with code behind
/asp:Content>
ApplicationPage1.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace CustomApplicationPages {

public class ApplicationPage1 : LayoutsPageBase {

// add control fields to match controls tags on .aspx page
protected Label lblSiteTitle;
protected Label lblSiteID;

protected override void OnLoad(EventArgs e) {

// get current site and web
SPSite siteCollection = this.Site;
SPWeb site = this.Web;

// program against controls on .aspx page
lblSiteTitle.Text = site.Title;
lblSiteID.Text = site.ID.ToString().ToUpper();
}

}
}
Creating an Application Page with the SPGridView Control
You can see that the class named ApplicationPage2 works together with a custom helper class named PropertyCollectionBinder to create an ADO.NET DataTable object filled with information about the current site and site collection. The DataTable object is being used in this example because its contents can be used to populate SPGridView by using standard ASP.NET data binding techniques.
protected override void OnLoad(EventArgs e)
{
SPSite siteCollection = this.Site;
SPWeb site = this.Web;
// PropertyCollectionBinder pcb = new PropertyCollectionBinder();
PropertyCollectionBinder pcb = new PropertyCollectionBinder();
pcb.AddProperty("Site Title", site.Title);
pcb.AddProperty("Site ID", site.ID.ToString().ToUpper());
pcb.AddProperty("Site Master Page Url", site.MasterUrl);
pcb.AddProperty("Site URL", site.Url);
pcb.AddProperty("Site Collection URL", siteCollection.Url);
pcb.AddProperty("Site Collection ID", siteCollection.ID.ToString().ToUpper());
pcb.AddProperty("Current User Name", site.CurrentUser.Name);
pcb.AddProperty("Is User Site Collection Admin", site.UserIsSiteAdmin.ToString());
pcb.AddProperty("Is User Site Admin", site.UserIsWebAdmin.ToString());
pcb.AddProperty("Site User Count", site.SiteUsers.Count.ToString());
pcb.AddProperty("Host Name", siteCollection.HostName);
pcb.AddProperty("Zone", siteCollection.Zone.ToString());
pcb.AddProperty("Site Collection System Account", siteCollection.SystemAccount.Name);
pcb.BindGrid(grdPropertyValues);
}
%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
%@ Assembly Name="CustomApplicationPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d4e5777b16a5749f" %>

%@ Page Language="C#" MasterPageFile="~/_layouts/application.master"
Inherits="CustomApplicationPages.ApplicationPage2"
EnableViewState="false" EnableViewStateMac="false" %>

%@ Register Tagprefix="SharePoint"
Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

asp:content id="Main" contentplaceholderid="PlaceHolderMain" runat="server">

SharePoint:SPGridView runat="server"
ID="grdPropertyValues"
AutoGenerateColumns="false"
RowStyle-BackColor="#DDDDDD"
AlternatingRowStyle-BackColor="#EEEEEE" />

/asp:Content>
PropertyCollectionBinder.cs
{

protected DataTable PropertyCollection = new DataTable();

public PropertyCollectionBinder() {
PropertyCollection.Columns.Add("PropertyName", typeof(string));
PropertyCollection.Columns.Add("PropertyValue", typeof(string));
}

public void AddProperty(string PropertyName, string PropertyValue) {
DataRow newRow = PropertyCollection.Rows.Add();
newRow["PropertyName"] = PropertyName;
newRow["PropertyValue"] = PropertyValue;
}

public void BindGrid(SPGridView grid) {

SPBoundField fldPropertyName = new SPBoundField();
fldPropertyName.HeaderText = "Property Name";
fldPropertyName.DataField = "PropertyName";
grid.Columns.Add(fldPropertyName);

SPBoundField fldPropertyValue = new SPBoundField();
fldPropertyValue.HeaderText = "Value";
fldPropertyValue.DataField = "PropertyValue";
grid.Columns.Add(fldPropertyValue);

grid.Width = new Unit(400);

grid.AutoGenerateColumns = false;
grid.DataSource = PropertyCollection.DefaultView;
grid.DataBind();


}
}
Restricting Application Pages to Site Administrators
Application pages are often designed to provide information and functionality
that should only be accessible to site administrators.
Let’s start by revisiting the creation of a CustomAction element within a feature. You can add an attribute named RequireSiteAdministrator and assign it a value of true so that the menu item only displays to those users who are also site administrators.
RequireSiteAdministrator="True"
While this provides a good start by hiding the menu item from users who are not site
administrators, it doesn’t provide a truly secure solution. The application page itself will still be accessible to any user who knows the URL. When you want to lock down an application page in a secure manner, you can accomplish this by overriding the RequireSiteAdministrator property of the LayoutsPageBase base class as shown in the following code.
public class ApplicationPage3 : LayoutsPageBase {
protected override bool RequireSiteAdministrator {
get { return true; }
}
protected override void OnLoad(EventArgs e) {
// your code goes here
} }
{
// get current site and web
SPSite siteCollection = this.Site;
SPWeb site = this.Web;

lblSiteTitle.Text = site.Title;
lblSiteUrl.Text = site.Url.ToLower();
lblSiteCollectionUrl.Text = siteCollection.Url.ToLower();
lstLists.Items.Clear();
foreach (SPList list in site.Lists) {
lstLists.Items.Add(list.Title);
}
lstLists.Rows = lstLists.Items.Count;
lstSiteUsers.Items.Clear();
foreach (SPUser user in site.SiteUsers) {
lstSiteUsers.Items.Add(user.Name);
}
lstSiteUsers.Rows = lstSiteUsers.Items.Count;

}
Adding a Custom Menu Item to the ECB (EditControlBlock)Menu

CustomAction Id="CustomApplicationPage4"
RegistrationType="List"
RegistrationId="101"
ImageUrl="/_layouts/images/GORTL.GIF"
Location="EditControlBlock"
Sequence="240"
Title="Application Page 4" >
urlaction url="~site/_layouts/CustomApplicationPages/ApplicationPage4.aspx?ItemId={ItemId}&ListId={ListId}">
/customaction>
Note that 101 is a list type identifier that applies to all document libraries. WSS dynamically replaces the {ListId} token with the identifying GUID for the current list or document library.
WSS dynamically replaces the {ItemId} token with the integer identifier for the current list item or document.
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;

lblSiteTitle.Text = site.Title;
lblSiteUrl.Text = site.Url.ToLower();
string ListId = Request.QueryString["ListId"];
lblListID.Text = ListId;
SPList list = site.Lists[new Guid(ListId)];
lblListTile.Text = list.Title;
lblRootFolderUrl.Text = list.RootFolder.Url;
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 (list is SPDocumentLibrary) {
SPDocumentLibrary documentLibrary = (SPDocumentLibrary)list;
lblDocumentTemplateUrl.Text = documentLibrary.DocumentTemplateUrl;

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();
}
}
Imp Points
1-If in IIS website has 10 ASP.NET app u have to create explicitly 10 virtual directories.But in WebApp u no need to go Mgr to create Virtual Dir.It is a single process for creaing n no of SiteCollections.
2-For each Asp.net APP u have to maintain 1 web.config.But in MOSS only one web.config for a WEB APP.In this u can maintain n no of site collections.

No comments: