Designing Site Pages by Using Controls


We have dealt with the nuts and bolts of site pages, page templates, and safe mode processing. It is now time to take a step back and discuss the development of page templates from a design perspective. In particular, we will discuss how to construct page templates by adding server-side controls to obtain the functionality and user interface components that you need.

In the ASP.NET programming model, two categories of server-side controls exist: custom controls and user controls, both of which are useful when designing page templates. Custom controls are more lightweight and must be compiled into an assembly DLL before being deployed to the front-end Web server. User controls are more productive because you can use the visual designer supplied by Visual Studio to create them.

After an overview of the use of custom controls and user controls, this section will address the creation of Web Part pages by creating a page template with one or more Web Part zones. During this discussion, we will explore the WSS infrastructure that makes browser-based user customization through Web Part possible.

Constructing Pages with Custom Controls

Let’s begin with a simple example of a custom control. A server-side control in ASP.NET is defined as a class that inherits from the Control class. However, developers often choose to create custom controls by deriving from a richer class named WebControl, which inherits from the Control class. The following code example illustrates a custom control class that inherits from WebControl and implements “Hello World” functionality by overriding the RenderContents method and adding some simple code that programs against the WSS object model.

  using System.Web.UI; using System.Web.UI.WebControls; using Microsoft.SharePoint; namespace CustomSitePages {   public class CustomControl1 : WebControl {     protected override void RenderContents(HtmlTextWriter output) {       SPWeb site = SPContext.Current.Web;       output.Write("Current Site: " + site.Title);       output.Write("<br/>");       output.Write("Current Site ID: " + site.ID.ToString());     }   } } 

You have two choices as to where to deploy an assembly DLL that contains a custom control when you want to use it in a site page. First, you can compile the assembly DLL with a strong name and install it in the Global Assembly Cache. Alternatively, you can deploy the assembly DLL by placing it inside the root directory of the hosting Web application inside a nested directory named bin. Note that when you plan to deploy the assembly DLL with custom controls in the bin directory, you have the option of compiling it with or without a strong name.

Once the assembly DLL with the custom control is properly deployed, you can then reference it within a page template by using the ASP.NET Register directive. The following code example displays a page template that uses the custom control shown previously.

  <%@ Page MasterPageFile="~masterurl/default.master"     meta:prog %> <%@ Register Assembly="CustomSitePages, ... "     Namespace="CustomSitePages" TagPrefix="CustomSitePages" %> <asp:Content       ContentPlaceHolder      runat="server"> <h3>A custom control example</h3> <CustomSitePages:CustomControl1  runat="server" /> </asp:Content> 

As you can see, adding a Register directive is just like adding an assembly reference to a project in Visual Studio because it makes the public components inside the target assembly available for use within the page. However, the Register directive also defines a TagPrefix attribute with a value of CustomSitePages. This TagPrefix value is then used to instantiate instances of the control within the page.

 <CustomSitePages:CustomControl1  runat="server" />

When you navigate to Page02.aspx, you should see that the page renders the output of the control so that it is visible to the user. However, this works only while the hosting page remains in a ghosted state. Remember that customized pages allow only for controls that are registered as safe controls. If a user customizes Page02.aspx with the SharePoint Designer, the page begins to execute in safe mode, and the presence of a control that is not registered as a safe control results in the error message shown in Figure 3-5.

image from book
Figure 3-5: Safe mode processing does not allow controls that are not registered as safe controls.

To fix this problem, you must add a custom SafeControl entry to the hosting Web application’s web.config file. You can accomplish this by adding a SafeControl entry that looks like the following:

 <SafeControl   Assembly="CustomSitePages, ..."   Namespace="CustomSitePages"   TypeName="CustomControl1" />

Note that when you add a SafeControl entry, you can define the type name for the control class explicitly as shown here, or you can alternatively use a TypeName value of * to register all of the server-side controls and Web Parts within the specific namespace that reside in the target assembly DLL.

Constructing Pages with User Controls

User controls provide a more productive alternative to custom controls. They are easier to develop because they are deployed on the front-end Web server as simple text files with an .ascx extension. The ASP.NET runtime provides the functionality to parse these .ascx files at run time and compile them into assembly DLLs just as it does for .aspx files.

Let’s examine the source file for a simple user control. The following example of an .ascx file creates a simple user interface with a command button and a label and adds in an event handler to provide the classic “Hello World” functionality.

  <%@ Control Language="C#" %> <script runat="server">   protected void cmdButton1_Click(object sender, EventArgs e) {     lblStatus.Text = "Hello, World";   } </script> <asp:Button  runat="server" Text="Add Customer"             OnClick="cmdAddCustomer_Click" /> <br/> <asp:Label  runat="server" Text="" /> 

As you can see, it’s fairly easy to get started with user controls. You can even use notepad.exe to create and modify simple .ascx files. However, you will likely prefer using Visual Studio to develop .ascx files because it provides a user control editor. This visual editor provides significantly higher levels of productivity because you can use standard Visual Studio design tools, such as the control toolbox and property sheet shown in Figure 3-6.

image from book
Figure 3-6: Visual Studio provides a productivity-oriented designer for developing user controls.

It is important to understand that WSS does not support user customization of user controls. User controls are always loaded from the file system of the front-end Web server and compiled into assembly DLLs. Furthermore, user controls can be copied to the front-end Web server only by someone with farm-level administrative privileges. For these reasons, you can assume that you can always write in-line code in an .ascx file.

Assume that you want to write in-line code in a user control that programs against the WSS object model. That’s easy. All you have to do is add an assembly directive to the top of the .ascx file that references the four-part assembly name of Microsoft.SharePoint.dll. You can also add an Import directive to import one or more namespaces to make your code more concise.

  <%@ Control Language="C#" %> <%@ Assembly Name="Microsoft.SharePoint, ..." %> <%@ Import Namespace="Microsoft.SharePoint" %> <script runat="server">   protected override void OnLoad(EventArgs e) {     SPWeb site = SPContext.Current.Web;     lblDisplay.Text = "Current Site: " + site.Url;   } </script> <asp:Label  runat="server" /> 

In Chapter 2, you were introduced to the virtual _layouts directory and learned that this was the proper place to deploy application pages. WSS provides a similar virtual directory for deploying user controls. Inside the TEMPLATE directory resides a nested directory named CONTROLTEMPLATES. This directory contains many different user controls that are deployed as part of the standard WSS installation.

The CONTROLTEMPLATES directory is also a place where you should deploy custom user control files. However, it’s a good practice to create your own nested directory inside the CONTROLTEMPLATES directory to avoid potential file name conflicts. The CustomSitePages project creates a company-specific inner directory named Litware and copies its user controls into that directory. Each custom user control is copied to a physical path that looks like the following:

 TEMPLATES/CONTROLTEMPLATES/Litware/UserControl1.ascx

Each Web application is configured with a virtual directory named _controltemplates that points to the physical CONTROLTEMPLATES directory. This makes it possible to reference any user control file by using a standard path relative to the hosting Web application. For example, one of the user controls from the CustomSitePages project can be referenced by using a virtual path that looks like the following:

 ~/_controltemplates/Litware/UserControl1.ascx

When deploying user controls, it’s important to remember that they follow the same rules with respect to safe mode processing. If you want to place a user control on a site page that might be customized, the .ascx file must be registered as a safe control in the web.config file of the hosting Web application. Fortunately, you don’t have to worry about this if you deploy your custom user controls inside the virtual _controltemplates directory because the standard web.config file for a Web application already contains the following SafeControl entry:

 <SafeControl   src="/books/4/221/1/html/2/~/_controltemplates/*"   IncludeSubFolders="True"   Safe="True"   AllowRemoteDesigner="True" />

Now that you have seen how to create and properly deploy a user control, the final step is constructing a page template that references the .ascx file and creates an instance. Similar to constructing pages with custom controls, this is accomplished by placing a Register directive on the page template. However, the process is different with user controls because the Register directive requires an src attribute that points to the virtual path of the target .ascx file.

  <%@ Page MasterPageFile="~masterurl/default.master"     meta:prog %> <%@ Register TagPrefix="luc" TagName="UserControl1"     src="/books/4/221/1/html/2/~/_controltemplates/Litware/UserControl1.ascx" %> <asp:Content runat="server" ContentPlaceHolder>   <luc:UserControl1  runat="server" /> </asp:Content> 

You have now seen all of the steps involved with constructing site pages using custom controls and user controls. This provides you with a strategy to create components that are reusable and versionable, and also provides you with a technique for adding whatever custom code you want to pages that are running in safe mode.

Note that all techniques shown here for constructing pages with custom controls and user controls can be used within custom application pages in the same fashion as they are in site pages. The one major difference is that application pages do not support user customization and never run in safe mode. If you want to create a custom control or user control that is used only on application pages, you do not need to worry about registering controls as safe controls in the web.config file.

Designing Web Part Pages

Web Parts provide a valuable dimension to WSS. In particular, Web Parts make it possible for a site owner to customize a site page with changes that are seen by all users. Web Parts go even further to allow individual users to add personalization changes that are seen only by them. WSS provides the underlying mechanisms to track all of this customization and personalization inside the content database along with all of the other site-related data.

Before diving into the details of how Web Part pages work, two important aspects of their architecture must be noted. First, support for customizing and personalizing Web Parts is available in site pages but not in application pages, thus giving site pages a clear design advantage over application pages.

Second, adding and customizing Web Parts does not require customizing the Web Part pages that host them. A Web Part page defines Web Part zones but does not define what goes inside these zones. Instead, all of the data for tracking Web Part instances and their customization and personalization data are kept in separate tables inside the content database. This means that a Web Part page can remain in a ghosted state even though users are continually adding, customizing, and personalizing the Web Parts within its zone.

Web Part pages in a WSS 3.0 site are built on top of the new Web Part infrastructure introduced with ASP.NET 2.0. To create a Web Part page in an ASP.NET 2.0 application, you must create an .aspx page that contains exactly one instance of a control named WebPartManager and one or more WebPartZone controls. The WebPartManager is responsible for managing the lifetime of Web Part instances as well as serializing Web Part–related data so that they can be stored and retrieved from the tables in the ASP.NET services database.

The Web Part infrastructure of WSS 3.0 does not use the standard WebPartManager control from ASP.NET. Instead, WSS relies on a specialized control named SPWebPartManager that derives from the ASP.NET 2.0 WebPartManager control. The SPWebPartManager control overrides the standard behavior of the WebPartManager control to persist Web Part data inside the WSS content database instead of inside the ASP.NET services database.

In most cases, you don’t have to worry about dealing with the SPWebPartManager control directly because the one and only required instance of the SPWebPartManager is already defined in the standard default.master page. When you create a site page that links to default.master, the SPWebPartManager control is automatically added to the page. Therefore, you simply need to add one or more WebPartZone controls.

Two things must be done when creating a page template for a Web Part page. The first is to inherit from the WebPartPage class that is defined inside the Microsoft.SharePoint.dll assembly. The second is to add one or more WebPartZone controls. Note that you must use the WebPartZone control defined by the WSS team and not the one of the same name defined by the ASP.NET team.

To add WebPartZone controls to a page template, you must add a Register directive that imports all of the controls from the Microsoft.SharePoint.dll assembly defined in the Microsoft.SharePoint.WebPartPages namespace as shown in the following page template definition.

  <%@ Page MasterPageFile="~masterurl/default.master"     Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,               Microsoft.SharePoint, [full 4-part assembly name]"     meta:prog %> <%@ Register Tagprefix="WebPartPages"     Namespace="Microsoft.SharePoint.WebPartPages"     Assembly="Microsoft.SharePoint, ..." %> <asp:Content  runat="server" ContentPlaceHolder > <h3>Custom Web Part page</h3> <table width="100%">   <tr>     <td valign="top" style="width:50%">         <WebPartPages:WebPartZone  runat="server"                                   FrameType="TitleBarOnly"                                   Title="Left Web Part zone" />     </td>     <td valign="top" style="width:50%">         <WebPartPages:WebPartZone  runat="server"                                   FrameType="TitleBarOnly"                                   Title="Right Web Part zone" />     </td>   </tr> </table> </asp:Content> 

It is easier to create pages that host Web Parts in the WSS framework than in the ASP.NET Framework. For example, when you design an ASP.NET application that involves Web Parts, you are required to add logic to each page that interacts with the WebPartManager control to manage the display mode. It is also necessary to explicitly add controls, such as Editor Zones and Catalog Zones, to the page so that users can customize existing Web Parts as well as add new Web Parts.

Fortunately, you don’t need to worry about managing the display mode or adding Editor Zones and Catalog Zones when creating Web Part pages for WSS. When you create a Web Part page that inherits from the WebPartPage class, all of this work is done for you behind the scenes. The Site Actions menu automatically provides the Edit Page command that allows the user to enter a mode for adding and customizing Web Parts.

In the CustomSitePages project, three different site pages are provisioned from the page template named WebPartPage.aspx. If you navigate to the first site page named WebPartPage01.aspx and select the Edit Page command from the Site Actions menu, you will see that there are two empty zones, as shown in Figure 3-7. At this point, you can use basic WSS support to add a new Web Part instance as you would to any other Web Part page, such as default.aspx.

image from book
Figure 3-7: A Web Part page is designed with one or more Web Part zones.

When you provision a Web Part page from a page template, it initially contains no Web Parts in any of its Web Part zones. While you could rely on users manually adding Web Parts to your pages, it is more convenient and reliable for you to use a technique in which you prepopulate Web Part zones with whatever Web Parts your business solution requires.

There are two common techniques for adding a Web Part instance to a Web Part zone. The first technique involves a declarative approach used inside a feature in which you define an AllUsersWebPart element inside a File element. The following example demonstrates the File element that is used in the CustomSitePages project to provision the Web Part page named WebPartPage02.aspx.

  <Elements xmlns="http://schemas.microsoft.com/sharepoint/">   <Module Path="PageTemplates" Url="SitePages" >     <File Url="WebPartPage.aspx" Name="WebPartPage02.aspx" Type="Ghostable" >       <!-- Add a Web Part to left zone -->       <AllUsersWebPart WebPartZone WebPartOrder="0">         <![CDATA[           <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2"                    xmlns:iwp="http://schemas.microsoft.com/WebPart/v2/Image">             <Assembly>Microsoft.SharePoint, ...</Assembly>             <TypeName>Microsoft.SharePoint.WebPartPages.ImageWebPart</TypeName>             <FrameType>None</FrameType>             <Title>Watch My Gears Run</Title>             <iwp:ImageLink>/_layouts/images/GEARS_AN.GIF</iwp:ImageLink>           </WebPart>         ]]>       </AllUsersWebPart>     </File>   </Module> </Elements> 

As you can see, a File element can contain an inner AllUsersWebPart element that references a target Web Part zone and includes serialized data for the Web Part instance to be created. We will revisit the inner WebPart element in more detail in Chapter 4 when we discuss Web Part description files.

The second technique for adding a Web Part instance to a Web Part page involves writing code against the WSS object model. An example of this type of code is supplied in the FeatureActivated event handler for the CustomSitePages project. The code obtains a reference to the SPFile object associated with WebPartPage03.aspx and uses an SPLimitedWebPartManager object to add a new Web Part instance to a particular target zone.

 public override void FeatureActivated(                        SPFeatureReceiverProperties properties) {   // acquire objects for site, page and limited Web Part Manager   SPWeb site = (SPWeb)properties.Feature.Parent;   SPFile page = site.GetFile("SitePages/WebPartPage03.aspx");   SPLimitedWebPartManager mgr;   mgr = page.GetLimitedWebPartManager(PersonalizationScope.Shared);   // add Web Part to Right Zone   ImageWebPart wp1 = new ImageWebPart();   wp1.ChromeType = PartChromeType.None;   wp1.ImageLink = @"/_layouts/images/IPVW.GIF";   mgr.AddWebPart(wp1, "RightZone", 0); }

The advantage to using the first technique is that Web Parts can be added to pages with declarative logic in the same place where the actual page is being provisioned. The advantage of using the second approach involving code is that it is more flexible. While you can execute code that adds a Web Part instance during feature activation, you can also execute the same code long after the feature is activated. For example, imagine a scenario in which you would like to write the code required to enumerate through every site within a farm to add a special Web Part to a target zone on every home page. The WSS object model makes it possible to automate this type of administrative task with Web Part pages.




Inside Microsoft Windows Sharepoint Services Version 3
Inside Microsoft Windows Sharepoint Services Version 3
ISBN: 735623201
EAN: N/A
Year: 2007
Pages: 92

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net