Вы находитесь на странице: 1из 97

Cornerstone Application

Framework Training

Class 1

1
Table of Contents
Cornerstone History.............................................................................................................................................3
Class Setup...........................................................................................................................................................3
Architecture Overview.........................................................................................................................................4
Developing UIs with Cornerstone vs. Classic ASP.NET.....................................................................................5
Project Structure and Conventions......................................................................................................................5
Developing the HelloWorld Solution..................................................................................................................6
Module 1: Creating the Application Solution..................................................................................................7
Module 2: Integrating the ValueMapper........................................................................................................14
Module 3: Adding a Controller Project..........................................................................................................22
Module 4: Form Layout and Handling Page Events......................................................................................27
Module 5: Consuming Web Services.............................................................................................................37
Module 6: Populating a GridView with Web Service Data...........................................................................55
Module 7: HelloWorld Base Page and Using the Cornerstone SearchControl..............................................76
Module 8: Consuming Data from a Database................................................................................................88
Advanced Topics................................................................................................................................................97
Appendix: Coding Standards.............................................................................................................................97
Appendix: ASP.NET Page Lifecycle.................................................................................................................97
Appendix: Level 3 Environment Concerns.......................................................................................................97

2
Cornerstone History
The Cornerstone Application Framework is the evolution of an idea that was first put into practice with the SOE
initiative. The goal was to create a consistent, effective toolkit that enables rapid application development
cycles by allowing the developer to concentrate more on implementing business requirements and less on
tweaking the UI. Cornerstone provides all the building blocks necessary to get a standardized Level 3
application up and running in no time. After several years of development and testing, this toolkit has now been
made available to a wider audience of Level 3 developers and will continue to live up to it’s initial purpose by
enabling developers to react quickly and produce outstanding results in our continually changing business
environment.

Class Setup
This class is designed to give you hands-on experience with Cornerstone.
You will need the following on your development machine:
1. Visual Studio 2005 with Service Pack 1
2. The latest version of the ASP.NET 2.0 AJAX Extensions (http://www.asp.net/ajax/downloads/)
3. Cornerstone template and xsd files installed (your instructor will help if you have not already done this)
4. Remote access enabled (you will use Microsoft Terminal Server Client to connect to your machine)

3
Architecture Overview
The controls, modules, and other primary features of Cornerstone are entirely compatible with and may be used
by a traditional ASP.NET application, but have been designed with a particular reference architecture in mind.
At a high-level this architecture is based on a standard three-tier MVC approach containing presentation,
controller, and data access levels.

The Cornerstone reference design dismisses use of the .ASPX page and relies entirely on the codebehind
(aspx.cs) and related embedded controls as the presentation tier. This allows for a more consistent control tree
and simplifies debugging. Many of the Cornerstone controls are instantiated by using L3ControlFactory, which
adheres to the factory pattern and provides consistency.

The controller tier acts as a conduit between the presentation tier and the data access tier. It processes and
responds to events and routes data accordingly. The flow controller, which guides page flow and manages state
and transfer parameters, also resides here.
4
The data access tier encapsulates all web service calls and database interaction. A ServiceFactory is used to
instantiate these object based on UDDI endpoints or provides application independence by seamlessly allowing
for stubs (mock data) to be used in their place. Enabling or disabling service stubs is simple process involving a
web.config change, and can be performed at runtime.

Developing UIs with Cornerstone vs. Classic ASP.NET


Developing a UI with Cornerstone differs from building it in the classic ASP.NET fashion in that the
1. VS Designer is not used (although it's been discussed that a future version of Cornerstone web controls
could be made to support the VS Designer)
2. Page layout and controls are controlled entirely in the code-behind file
3. There is only one line of text in the .aspx file of the page

Project Structure and Conventions


• (Insert project diagram here)
• Summary of naming conventions for
 Projects
 Pages
 Controls
 Classes
 Namespaces
• Summary of Coding standards
• Summary of File location

5
Developing the HelloWorld Solution

6
Module 1: Creating the Application Solution
Module Goal:
In this module we will begin building the sample application HelloWorld with the following features:
• Cornerstone enable
• Single page that displays a static message
• Header and Footer user controls
• Styling based on a CSS file

7
Procedure 1.1: Creating the HelloWorld web site
1. Create a folder on the c: drive called "HelloWorld_Solution". This is where the application source files
will be kept.
2. Open Visual Studio
3. Select FileNewWeb Site…
4. Choose "ASP.NET AJAX-Enabled Web site" (or depending on your Visual Studio installation "ASP
.NET AJAX-Enabled Web Application"), set the Location to "c:\HelloWorld_Solution\HelloWord", the
Language to "Visual C#" and hit OK

5. In the Solution Explorer window, right click the HelloWorld web site and select Property Page.
6. Add a reference to the Cornerstone.Web.dll assembly from the path your instructor gives you.

8
Procedure 1.2: Adding a HelloWorld page
1. Delete the web page Default.aspx.
2. Right click the HelloWorld web site and add a new web form called "HelloWorldPage.aspx"

3. Open the Source view for HelloWorldPage.aspx and delete all but the first line

4. Right click the HelloWorld.aspx file and select "Set As Start Page"
5. Open the code-behind file for HelloWorldPage.aspx.cs by clicking the '+' next HelloWorldPage.aspx.cs
in the Solution Explorer and double clicking the HelloWorldPage.aspx.cs file.
6. Delete all of the "using …" statements at the top of the file except the one for System.
7. Add the statement "using Level3.Cornerstone.Web.WebControls;" to the top of the file under "using
System;"
8. Change the base class of this page from "System.Web.UI.Page" to "L3PageTemplate"
9. Delete the entire Page_Load method.
10. Add the following methods:
protected override void OnInit(EventArgs e)
9
{
base.OnInit(e);
EnsureChildControls();
}

protected override void CreateChildControls()


{
base.CreateChildControls();
Controls.Add(L3ControlFactory.CreateLabel("Hello World!"));
}

11. Save all files and browse the page.

10
Source File Code 1.2: HelloWorldPage.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="HelloWorldPage.aspx.cs"
Inherits="HelloWorldPage" %>

Source File Code 1.2: HelloWorldPage.aspx.cs


using System;
using Level3.Cornerstone.Web.WebControls;

public partial class HelloWorldPage : L3PageTemplate


{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
EnsureChildControls();
}
protected override void CreateChildControls()
{
base.CreateChildControls();
Controls.Add((L3ControlFactory.CreateLabel("Hello World")));
}
}

11
Procedure 1.3: Adding a Header, Footer, and Style Sheet
1. Create a folder in the web site called "Styles"
2. Add the file HelloWorldStyle.css to the Styles folder from the location your instructor gives you.
3. Open Web.config and add the following under the line "</configSections>"
<!-- Cornerstone specific settings -->
<appSettings>
<!-- Location of the Header Control to use for the template -->
<add key="HeaderControlLocation" value="UserControls/Header.ascx"/>
<!-- Location of the Footer Control to use for the template -->
<add key="FooterControlLocation" value="UserControls/Footer.ascx"/>
</appSettings>

4. Right click the HelloWorld web site and select "New Folder"
5. Rename the new folder "UserControls". This is where the header and footer for the application pages
will be kept.
6. Right click the "UserControls" folder and select "Add New Item…"
7. Add a "Web User Control" called "Header.ascx"
8. Repeat the previous two steps to add "Footer.ascx"
9. Add the following to Header.ascx source view
10. Open the source view for Header.ascx and add the following to the end of the file:
<link href="Styles/HelloWorldStyle.css" rel="stylesheet" type="text/css">
<div id="headerFrame"> HelloWorld Header </div>

11. Open the source view for Footer.ascx and add the following to the end of the file:
<div id="footerFrame"> HelloWorld Footer </div>

12. Save all files and browse the page.

12
Source File Code 1.3: Header.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Header.ascx.cs"
Inherits="UserControls_Header" %>
<link href="Styles/HelloWorldStyle.css" rel=stylesheet type="text/css" />
<div id="headerFrame">HelloWorld Header</div>

Source File Code 1.3: Footer.ascx


<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Footer.ascx.cs"
Inherits="UserControls_Footer" %>
<div id="footerFrame">HelloWorld Footer</div>

13
Module 2: Integrating the ValueMapper
Module Goal:
In this module we will begin using the ValueMapper class. It is used extensively throughout Cornerstone
applications to hold textual content for display values and mapping information for data object relationships. At
the end of this module, the HelloWorld solution will have:
• New Class Library project called Common which blah, blah, blah. Se the architecture section
• A page with static text populated from the ValueMapper

14
Procedure 2.1: Creating the HelloWorld.Common project and adding the ValueMapper
1. Create a new class library project in the solution called HelloWorld.Common using the path
c:\HelloWorld_Solution.
2. Delete the Class1.cs file.
3. Add a reference in the project to System.Web

4. Add a reference to the Level3.Cornerstone.Common.dll and Level3.Cornerstone.Web.dll assemblies


from the path your instructor gives you.
5. Add a new Class to the HelloWorld.Common project called HWValueMapper.cs.

6. Remove all of the using statements in the HWValueMapper.cs class file.


Add the following using statements to the class:
15
using System.IO;
using System.Web;
using Level3.Cornerstone.Common.ValueMapper;

7. Make the class public.


8. Add a member variable to the class " private static IValueMapper instance;"
9. Add a public property called "Instance" that returns an IValueMapper
public static IValueMapper Instance
{
get
{
if (instance == null)
{
string ResourceFile = "App_LocalResources\\HWValueMapper.xml";
FileStream stream = new FileStream(HttpContext.Current.Server.MapPath(ResourceFile),
FileMode.Open, FileAccess.Read);
instance = ValueMapperFactory.Create(new Stream[] { stream });
}

return instance;
}
}

10. Right click the Common project and build the project.

16
Source File Code 2.1: HWValueMapper.cs
using System.IO;
using System.Web;
using Level3.Cornerstone.Common.ValueMapper;

namespace HelloWorld.Common
{
/// <summary>
/// Singleton Wrapper on <see cref="IValueMapper"/>
/// </summary>
public class HWValueMapper
{
private static IValueMapper instance;

private HWValueMapper()
{
}

public static IValueMapper Instance


{
get
{
if (instance == null)
{
string ResourceFile = "App_LocalResources\\HWValueMapper.xml";
FileStream stream = new
FileStream(HttpContext.Current.Server.MapPath(ResourceFile), FileMode.Open,
FileAccess.Read);
instance = ValueMapperFactory.Create(new Stream[] { stream });
}

return instance;
}
}
}
}

17
Procedure 2.2: Creating the ValueMapper resource file
1. Right-click the HelloWorld_Solution web site, and select "App_LocalResources" the "Add ASP.NET
Folder" menu.
2. Right click the "App_LocalResources folder and add an XML file called HWValueMapper.xml.
3. Add the following line to the bottom of HWValueMapper.xml:

<Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">
<Values>
<ValueItem key="helloworld" presentationValue="Hello World! (from the Value Mapper)"/>
</Values>
</Mapping>

18
Source File Code 2.2: HWValueMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">
<Values>
<ValueItem key="helloworld" presentationValue="HelloWorld!(from the Value
Mapper)"/>
</Values>
</Mapping>

19
Procedure 2.3: Using the ValueMapper in HelloWorldPage
1. Add a reference to the HelloWorld.Common project to the HelloWorld web site.
2. Open HelloWorld.aspx.cs
3. Add "using HelloWorld.Common;"
4. Add a line break and a label to the pages Control collection with the following lines in the
CreateChildControls method:
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentationValue("helloworld")));

5. Save all files and browse the page.

20
Source File Code 2.3: HelloWorldPage.aspx.cs
using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.WebControls;

public partial class HelloWorldPage : L3PageTemplate


{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
EnsureChildControls();
}
protected override void CreateChildControls()
{
base.CreateChildControls();
Controls.Add((L3ControlFactory.CreateLabel("Hello World")));
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentat
ionValue("helloworld")));
}
}

21
Module 3: Adding a Controller Project
Module Goal:
In this module we introduce the Controller layer which routes data between the UI and the service layers. We
will process and responds to events from the page. At the end of this module solution will have:
• A new class library project called Controller
• A controller class to hold logic for the HelloWorldPage

22
Procedure 3.1: Creating the HelloWorld.Web.Controllers project and adding a controller
1. Add a new class library project to the solution called HelloWorld.Web.Controllers on the path
c:\HelloWorld_Solution.
2. Delete the Class1.cs file in the new project.
3. Add a new class file called HelloWorldController.cs to the project.
4. Open the class file and make the class definition public.
5. Delete all of the "using" statements.
6. Create a public parameterless method in the HelloWorldController class called
GenerateHelloWorldDisplayText that returns the string "Hello World! (from the controller)"
7. Right click the HelloWorld.Web.Controllers project and build the project.

23
Source File Code 3.1: HelloWorldController.cs
namespace HelloWorld.Web.Controllers
{
public class HelloWorldController
{
public string GenerateHelloWorldDisplayText()
{
return "Hello World! (from the controller)"
}
}
}

24
Procedure 3.2: Using the HelloWorld Controller
1. Add a reference to the HelloWorld.Web.Controllers project to the HelloWorld web site.
2. Open the HelloWorldPage.aspx.cs file
3. Add the using statement "using HelloWorld.Web.Controllers;"
4. Add a member variable to the class called "controller" with the statement:
HelloWorldController controller = new HelloWorldController();

5. Add a line break and a label control to the page and use the method GenerateHelloWorldDisplayText
from the controller to fill the text.
6. Save and view the page in the browser.

25
Source File Code 3.2: HelloWorldPage.aspx.cs
using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.WebControls;
using HelloWorld.Web.Controllers;

public partial class HelloWorldPage : L3PageTemplate


{
HelloWorldController controller = new HelloWorldController();

protected override void OnInit(EventArgs e)


{
base.OnInit(e);
EnsureChildControls();
}
protected override void CreateChildControls()
{
base.CreateChildControls();
Controls.Add((L3ControlFactory.CreateLabel("Hello World")));
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentat
ionValue("helloworld")));
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(controller.GenerateHelloWorldDispla
yText()));
}
}

26
Module 4: Form Layout and Handling Page Events
Module Goal:
In this module we will add page controls for handling a page's layout. We will also begin handling events using
a button control. At the end of this module the HelloWorldPage will have:
• A L3Border control
• A L3Form control
• A L3ButtonPanel control
• Feedback for the user with the ValidationManager
• Two buttons to get and clear labels
• An event handler for the button which calls the pages controller to populate a label

27
Procedure 4.1: Adding the L3Form and L3Border controls
1. In CreateChildControls() for HelloWorldPage.aspx.cs, add the line
L3Form form = new L3Form();

immediately below
base.CreateChildControls();

2. Use the "addRow" method of the new "form" object to add labels to the L3Form:
form.AddRow("Static:",L3ControlFactory.CreateLabel("Hello World!"));
form.AddRow("From ValueMapper:",
L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentationValue("helloworld")));
form.AddRow("From Controller:", controller.GenerateHelloWorldDisplayText());

3. Wrap the L3Form in a L3Border and add it to the pages controls below the last form.addRow statement:
Controls.Add(L3Border.WrapControl(form, "This is the L3Border control"));

4. Save and browse the page.

28
Source File Code 4.1: HelloWorldPage.aspx.cs
using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.WebControls;
using HelloWorld.Web.Controllers;

public partial class HelloWorldPage : L3PageTemplate


{
HelloWorldController controller = new HelloWorldController();

protected override void OnInit(EventArgs e)


{
base.OnInit(e);
EnsureChildControls();
}
protected override void CreateChildControls()
{
base.CreateChildControls();

L3Form form = new L3Form();

form.AddRow("Static:",L3ControlFactory.CreateLabel("Hello World!"));
form.AddRow("From ValueMapper:",
L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentationValue("helloworld"
)));
form.AddRow("From Controller:", controller.GenerateHelloWorldDisplayText());

Controls.Add(L3Border.WrapControl(form, "This is the L3Border control"));

Controls.Add((L3ControlFactory.CreateLabel("Hello World")));
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentat
ionValue("helloworld")));
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(controller.GenerateHelloWorldDispla
yText()));
}
}

29
Procedure 4.2: Adding the L3ButtonPanel and Event Handlers
1. Add the following items to the HWValueMapper.xml:
<!-- Button Labels-->
<ValueItem key="getvalues" presentationValue="Get Values" />
<ValueItem key="clearvalues" presentationValue="Clear Values" />
<ValueItem key="submit" presentationValue="Submit" />

2. Open HelloWorldPage.aspx.cs and add using statements for System.Web.UI.WebControls and


Level3.Cornerstone.Web.Images.
3. Add two private member variables of type Label to the HelloWorldPage class called
helloWorldFromValueMapper and helloWorldFromController
private Label helloWorldFromValueMapper = new Label();
private Label helloWorldFromController = new Label();

4. Optionally, to keep the page cleaner, you can remove the other labels we added in earlier modules.
5. Add the helloWorldFromController and helloWorldFromValueMapper labels to the form with the
following below the statement where the L3Form was created:
form.AddRow("From ValueMapper:", helloWorldFromValueMapper);
form.AddRow("From Controller:", helloWorldFromController);

6. Add an L3ButtonPanel with the statement:


L3ButtonPanel buttonPanel = new L3ButtonPanel();

7. Create two buttons and their click event delegates with the following statements:
Button getValuesButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("getvalues"));
getValuesButton.Click += getValuesButton_Click;

Button clearValuesButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("clearvalues"));
clearValuesButton.Click += clearValuesButton_Click;

8. Add the buttons to the L3ButtonPanel with the following statements:


buttonPanel.AddRightControl(getValuesButton);
buttonPanel.AddRightControl(clearValuesButton);

9. If you haven't done so already, remove the L3Border added in the previous procedure . Create a new
border and add it to the page with the statements:
L3Border border = L3Border.WrapControl(form, " Hello World L3 Border", L3Icon.World, buttonPanel);
Controls.Add(border);

10. Add the delegate methods for the buttons' click events with the following:
#region Button Events

private void getValuesButton_Click(object sender, EventArgs e)


{
helloWorldFromValueMapper.Text = HWValueMapper.Instance.GetPresentationValue("helloworld");
30
helloWorldFromController.Text = controller.GenerateHelloWorldDisplayText();
}

private void clearValuesButton_Click(object sender, EventArgs e)


{
InitializeValues();
}

#endregion

11. Create the InitializeValues method which resets the values of the labels:
private void InitializeValues()
{
helloWorldFromValueMapper.Text = "Click 'Get Values' to retrieve this.";
helloWorldFromController.Text = "Click 'Get Values' to retrieve this.";
}

12. Override the base pages OnPreRender event with the following (for organization purposes put this
method below the OnInit method):
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);

if (!Page.IsPostBack)
{
InitializeValues();
}
}

13. Save and browse the page. Click the two new buttons to make sure they both work.

31
Source File Code 4.2: HWValueMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">
<Values>
<ValueItem key="helloworld" presentationValue="HelloWorld! (from the Value
Mapper)"/>

<!-- Button Labels-->


<ValueItem key="getvalues" presentationValue="Get Values" />
<ValueItem key="clearvalues" presentationValue="Clear Values" />
<ValueItem key="submit" presentationValue="Submit" />

</Values>
</Mapping>

Source File Code 4.2: HelloWorldPage.aspx.cs


using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using HelloWorld.Web.Controllers;
using System.Web.UI.WebControls;

public partial class HelloWorldPage : L3PageTemplate


{
HelloWorldController controller = new HelloWorldController();
private Label helloWorldFromController = new Label();
private Label helloWorldFromValueMapper = new Label();

protected override void OnInit(EventArgs e)


{
base.OnInit(e);
EnsureChildControls();
}

protected override void OnPreRender(EventArgs e)


{
base.OnPreRender(e);

if (!Page.IsPostBack)
{
InitializeValues();
}
}

protected override void CreateChildControls()


{
base.CreateChildControls();

L3Form form = new L3Form();

form.AddRow("From ValueMapper:", helloWorldFromValueMapper);


form.AddRow("From Controller:", helloWorldFromController);

L3ButtonPanel buttonPanel = new L3ButtonPanel();


Button getValuesButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("getvalues"
));

32
getValuesButton.Click += getValuesButton_Click;

Button clearValuesButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("clearvalue
s"));
clearValuesButton.Click += clearValuesButton_Click;

buttonPanel.AddRightControl(getValuesButton);
buttonPanel.AddRightControl(clearValuesButton);

L3Border border = L3Border.WrapControl(form, " Hello World L3 Border",


L3Icon.World, buttonPanel);
Controls.Add(border);

Controls.Add(L3Border.WrapControl(form, "This is the L3Border control"));


}

#region Button Events

private void getValuesButton_Click(object sender, EventArgs e)


{
helloWorldFromValueMapper.Text =
HWValueMapper.Instance.GetPresentationValue("helloworld");
helloWorldFromController.Text = controller.GenerateHelloWorldDisplayText();
}

private void clearValuesButton_Click(object sender, EventArgs e)


{
InitializeValues();
}

#endregion

private void InitializeValues()


{
helloWorldFromValueMapper.Text = "Click 'Get Values' to retrieve this.";
helloWorldFromController.Text = "Click 'Get Values' to retrieve this.";
}
}

33
Procedure 4.3: Adding the Validation Manager
1. In HelloWorldPage.aspx.cs add a using statement for Level3.Cornerstone.Web.WebControls.Validation.
2. In the CreateChildControls method of HelloWorldPage.aspx.cs add the following statement:
ValidationManager.AddInfo("This is an example of event handling and the page lifecycle.");

3. In getValuesButton_Click add the following statement:


ValidationManager.AddSuccess("'Get Values' clicked.");

4. In clearValuesButton_Click add the following statement:


ValidationManager.AddSuccess("'Clear Values' clicked.");

5. Save and browse the page. Click on the buttons to see how the ValidationManager is displayed.

34
Source File Code: HelloWorldPage.aspx.cs
using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using HelloWorld.Web.Controllers;
using System.Web.UI.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

public partial class HelloWorldPage : L3PageTemplate


{
HelloWorldController controller = new HelloWorldController();
private Label helloWorldFromController = new Label();
private Label helloWorldFromValueMapper = new Label();

protected override void OnInit(EventArgs e)


{
base.OnInit(e);
EnsureChildControls();
}

protected override void OnPreRender(EventArgs e)


{
base.OnPreRender(e);

if (!Page.IsPostBack)
{
InitializeValues();
}
}

protected override void CreateChildControls()


{
base.CreateChildControls();

L3Form form = new L3Form();

form.AddRow("From ValueMapper:", helloWorldFromValueMapper);


form.AddRow("From Controller:", helloWorldFromController);

L3ButtonPanel buttonPanel = new L3ButtonPanel();


Button getValuesButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("getvalues"
));
getValuesButton.Click += getValuesButton_Click;

Button clearValuesButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("clearvalue
s"));
clearValuesButton.Click += clearValuesButton_Click;

buttonPanel.AddRightControl(getValuesButton);
buttonPanel.AddRightControl(clearValuesButton);

L3Border border = L3Border.WrapControl(form, " Hello World L3 Border",


L3Icon.World, buttonPanel);
Controls.Add(border);

Controls.Add(L3Border.WrapControl(form, "This is the L3Border control"));


35
ValidationManager.AddInfo("This is an example of event handling and the page
lifecycle.");
}

#region Button Events

private void getValuesButton_Click(object sender, EventArgs e)


{
helloWorldFromValueMapper.Text =
HWValueMapper.Instance.GetPresentationValue("helloworld");
helloWorldFromController.Text = controller.GenerateHelloWorldDisplayText();

ValidationManager.AddSuccess("'Get Values' clicked.");


}

private void clearValuesButton_Click(object sender, EventArgs e)


{
InitializeValues();

ValidationManager.AddSuccess("'Clear Values' clicked.");


}

#endregion

private void InitializeValues()


{
helloWorldFromValueMapper.Text = "Click 'Get Values' to retrieve this.";
helloWorldFromController.Text = "Click 'Get Values' to retrieve this.";
}
}

36
Module 5: Consuming Web Services
Module Goal:
In this module we will build a new project for consuming web services which utilizes the Level 3 UDDI
registry to different environments. We also establish the pattern of using an Interface to the web service which
allows us to create unit tests and stubs for the web service. At the end of the module the HelloWorld solution
will have:
• New HelloWorld.Services project for consuming web services
• A web reference to web services in the application TAI
• A ServiceFactory (see Architecture Overview section)
• An Interface definition for the TAI web service
• A stub for the TAI web service to use during development when the TAI service is not available
• A new page that populates a drop down list with data from the TAI web service

37
Procedure 5.1: Creating the HelloWorld.Services project and web reference
1. Create a new class library project in c:\HelloWorld_Solution called HelloWorld.Services.
2. Delete the file Class1.cs
3. Add references to Level3.Cornerstone.UDDIRegistry.dll and Level3.Cornerstone.Common from the
distribution folder.
4. Add the following to web.config under the node <configuration>:

<configSections>
<section name="ServiceProperties" type="Blank"/>
<section name="uddiConfiguration"
type="Level3.Cornerstone.UDDIRegistry.Configuration.UDDIRegistrySection, Level3.Cornerstone.UDDIRegistry,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</configSections>

5. Add the following to web.config above the node </configuration>. These values are used later to point at
the different environments where the web services are published:

<uddiConfiguration registryUrl="http://registry.env1.level3.com/registryservice/RegistryQueryService"
environment="ENV1" cacheTimeoutSeconds="3600">
<services>
<add name="TAI_WebServices"
registryServiceName="http://level3.com/enterprise/network_activation/tai/maint" contact="Schneider,
Kevin" provider="TAI"/>
</services>
</uddiConfiguration>

<ServiceProperties>
<ServiceItem name="TaiWebService" mockOn="false"/>
</ServiceProperties>

6. Add a web reference to the HelloWorld.Services project with URL =


http://taienv3ws.l3.com/tai/maint/ws?wsdl and Web Reference Name = WebServices.TAI.Maint

38
Procedure 5.2: Creating an Interface for the TAI web service
1. Add a folder to the HelloWorld.Services project called WebServices.
2. Add a new class file in the WebService folder called ITaiWebService.cs
3. Open ITaiWebService.cs and change the class to a public interface by changing "class" to "public
interface"
4. Add a "using" statement for HelloWorld.Services.WebServices.TAI.Maint.
5. Add a method signature to the interface for the "FindAllLocState" method in the TAI web service

39
Source File Code 5.2: ITaiWebService.cs
using HelloWorld.Services.WebServices.TAI.Maint;

namespace HelloWorld.Services.WebServices
{
public interface ITaiWebService
{
LocStateVO[] FindAllLocState(LocStateVO locStateVO);
}
}

40
Procedure 5.3: Creating an implementaion of the ITaiWebService interface
1. Add a new class called TaiWebService to the WebServices directory of the HelloWorld.Services project.
2. Make the class public.
3. Add the following to the using statements:
using System.Web.Services.Protocols;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.UDDIRegistry;

4. Inherit the ITaiWebService interface:


class TaiWebService : ITaiWebService

5. Add two private member variables:

private string serviceName = typeof(TAI_WebServices).Name;


private SoapHttpClientProtocol service;

6. Add a public constructor to the class with the following:

public TaiWebService()
{
service = new TAI_WebServices();
IRegistry registry = RegistryManager.Load();
registry.Bind(serviceName, service);
}

7. Implement the method FindAllLocState from the interface with:


public LocStateVO[] FindAllLocState(LocStateVO locStateVo)
{
return Array.ConvertAll((service as TAI_WebServices).findAllLocState(locStateVo),
new Converter<object, LocStateVO>(LocStateObjectConverter));
}

8. Add the LocStateObjConverter method to convert the generic objects returned by the TAI web service to
LocStateVOs:
public static LocStateVO LocStateObjectConverter(object obj)
{
return (LocStateVO)obj;
}

41
Source File Code 5.3: TaiWebService.cs
using System;
using System.Web.Services.Protocols;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.UDDIRegistry;

namespace HelloWorld.Services.WebServices
{
public class TaiWebService : ITaiWebService
{
private string serviceName = typeof(TAI_WebServices).Name;
private SoapHttpClientProtocol service;

public TaiWebService()
{
service = new TAI_WebServices();
IRegistry registry = RegistryManager.Load();
registry.Bind(serviceName, service);
}

#region ITaiWebService Members

public LocStateVO[] FindAllLocState(LocStateVO locStateVo)


{
return Array.ConvertAll((service as
TAI_WebServices).findAllLocState(locStateVo), new Converter<object,
LocStateVO>(LocStateObjectConverter));
}

#endregion

#region Converters

public static LocStateVO LocStateObjectConverter(object obj)


{
return (LocStateVO)obj;
}

#endregion
}

42
Procedure 5.4: Creating a stub for TAI web service
1. Add a folder in the HelloWorld.Services project called "Stubs"
2. Add a class file in the "Stubs" folder called TaiWebServiceStub.cs.
3. Add the using statements:
using HelloWorld.Services.WebServices;
using HelloWorld.Services.WebServices.TAI.Maint;

4. Make the class public and inherit the ITaiWebService interface.


5. Add the following methods to the class:
public LocStateVO[] FindAllLocState(LocStateVO locStateVo)
{
int numStates = 50;
LocStateVO[] locStates = new LocStateVO[numStates];

for (int i = 0; i < numStates; i++)


{
locStates[i] = BuildLocStateVO(i);
}

return locStates;
}

LocStateVO BuildLocStateVO(int id)


{
LocStateVO locStateVo = new LocStateVO();
locStateVo.name = "Name-" + id;
locStateVo.abbrev = "Abbrev-" + id;
locStateVo.lastUpdateDate = DateTime.Now.ToString();
locStateVo.lastUpdateUser = "User-" + id;

return locStateVo;
}

43
Source File Code 5.4: TaiWebServiceStub.cs
using System;
using HelloWorld.Services.WebServices;
using HelloWorld.Services.WebServices.TAI.Maint;

namespace HelloWorld.Services.Stubs
{
public class TaiWebServiceStub : ITaiWebService
{
#region ITaiWebService Members

public LocStateVO[] FindAllLocState(LocStateVO locStateVo)


{
int numStates = 50;
LocStateVO[] locStates = new LocStateVO[numStates];
for (int i = 0; i < numStates; i++)
{
locStates[i] = BuildLocStateVO(i);
}
return locStates;
}

#endregion

#region Helpers

LocStateVO BuildLocStateVO(int id)


{
LocStateVO locStateVo = new LocStateVO();
locStateVo.name = "Name-" + id;
locStateVo.abbrev = "Abbrev-" + id;
locStateVo.lastUpdateDate = DateTime.Now.ToString();
locStateVo.lastUpdateUser = "User-" + id;

return locStateVo;
}

#endregion
}
}

44
Procedure 5.5: Creating the ServiceFactory
The ServiceFactory instantiates services based on UDDI endpoints and seamlessly allows for stubs. An element
must be added to the serviceDictionary for each service type to be supported. The serviceDictionary is keyed
off of the interface type name and uses the service name to look up the mockOn value for that service in the
web.config ServiceProperties section. Based on this flag the service factory instantiates one of two
possibilities: the actual service or a stubbed implementation. In this way, live and mock data can be toggled at
runtime without a code change. A ServiceFactory subclass, named appropriately for your application, must
exist within your solution in order to have the proper scope necessary to access local service objects.

1. Add a new class file to HelloWorld.Services called HWServiceFactory.


2. Replace the code in this class file with the following:
using System;
using System.Collections.Generic;
using System.Text;
using HelloWorld.Services.Stubs;
using HelloWorld.Services.WebServices;
using Level3.Cornerstone.Common.ServiceFactory;

namespace HelloWorld.Services
{
public enum ServiceTypes
{
TaiWebService
}

/// <summary>
/// Factory for creating services
/// </summary>
/// <exception>ServicesFactoryException if unable to create the type specified.</exception>
public sealed class CSTServicesFactory
{
private static readonly IServiceFactory serviceFactory = new CSTServiceFactory();

private CSTServicesFactory()
{
}

public static TService Create<TService>() where TService : class


{
return (TService)ServicesFactory.Create(serviceFactory, typeof(TService));
}

/// <summary>
/// Creates the correct ServiceFactory based on the type.
/// </summary>
public class CSTServiceFactory : IServiceFactory
{
Dictionary<Type, ServiceFactory> serviceDictionary = new Dictionary<Type, ServiceFactory>();

internal CSTServiceFactory()
{
// Include code here to handle every service type.
serviceDictionary.Add(typeof(ITaiWebService), new
ServiceFactory(ServiceTypes.TaiWebService.ToString(), typeof(TaiWebService), typeof(TaiWebServiceStub)));
}

45
public ServiceFactory Create(object serviceType)
{
Type t = (Type)serviceType;
if (!serviceDictionary.ContainsKey(t))
{
throw new Exception(BuildErrorMessage(t.Name));
}
return serviceDictionary[t];
}

private string BuildErrorMessage(string serviceName)


{
StringBuilder msg = new StringBuilder();

msg.Append(string.Format("Service '{0}' is not defined in Service Factory/", serviceName));


msg.Append(Environment.NewLine);
msg.Append("Available Services Include:");
msg.Append(Environment.NewLine);

foreach (Type type in serviceDictionary.Keys)


{
msg.Append(type.Name);
msg.Append(Environment.NewLine);
}

return msg.ToString();
}
}
}
}
3. Save all files and build the HelloWorld.Services project.

46
Procedure 5.6: Creating a controller for the WebService
1. Add a project reference in the HelloWorld.Web.Controllers to the HelloWorld.Services project.
2. Add a reference in the HelloWorld.Web.Controllers to Level3.Cornerstone.Web.dll.
3. Add a class file to the HelloWorld.Web.Controllers project called WebServiceController.cs and make it
public.
4. Add a "using" for the following statements to the using
using System.Collections;
using HelloWorld.Services;
using HelloWorld.Services.WebServices;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.Web.WebControls.Validation;

5. Add a private member to the class with:

private ITaiWebService webService;

6. Add two class constructors for the class with:


public WebServiceController() : this(CSTServicesFactory.Create<ITaiWebService>())
{
}

public WebServiceController(ITaiWebService webService)


{
this.webService = webService;
}

7. Add the following public method (GetStates) and property (EmptyLocStateVO) to the class:

public SortedList GetStates()


{
try
{
LocStateVO[] locStates =
webService.FindAllLocState(BuildEmptyLocStateVO);
SortedList stateList = new SortedList();

foreach (LocStateVO locState in locStates)


{
stateList.Add(locState.abbrev,locState.name);
}

return stateList;
}
catch (Exception ex)
{
ValidationManager.AddFailure("GetStateNameAbbreviations failed: " + ex.Message);
return new SortedList();
}
}

public static LocStateVO EmptyLocStateVO


{
//The web service expects a null for "unset" integers, but .NET
//doesn't allow this. Compromise: Set INT fields equal to -1
47
//the service will read these as null
get
{
LocStateVO retVO = new LocStateVO();
retVO.sequenceLock = -1;
return retVO;
}
}

8. Save all files and build the HelloWorld.Web.Controllers project.

48
Source File Code 5.6: WebServiceController.cs
using System;
using System.Collections;
using HelloWorld.Services;
using HelloWorld.Services.WebServices;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.Web.WebControls.Validation;

namespace HelloWorld.Web.Controllers
{
public class WebServiceController
{
private ITaiWebService webService;

#region Constructors

public WebServiceController()
: this(CSTServicesFactory.Create<ITaiWebService>())
{
}

public WebServiceController(ITaiWebService webService)


{
this.webService = webService;
}

#endregion

#region Members
public SortedList GetStates()
{
try
{
LocStateVO[] locStates =
webService.FindAllLocState(EmptyLocStateVO());

SortedList stateList = new SortedList();

foreach (LocStateVO locState in locStates)


{
stateList.Add(locState.abbrev,locState.name);
}

return stateList;
}
catch (Exception ex)
{
ValidationManager.AddFailure("GetStateNameAbbreviations failed: " +
ex.Message);
return new SortedList();
}
}

public static LocStateVO EmptyLocStateVO


{
//The web service expects a null for "unset" integers, but .NET
//doesn't allow this. Compromise: Set INT fields equal to -1
//the service will read these as null
get
49
{
LocStateVO retVO = new LocStateVO();
retVO.sequenceLock = -1;
return retVO;
}
}
#endregion
}
}

50
Procedure 5.7: Populating a drop down list with data from the TAI web service
1. Add a new Cornerstone web page from the template to the HelloWorld web site called
WebService1.aspx.
2. Add a ValueItem to HWValueMapper.xml with:
<ValueItem key="statelist" presentationValue="States" />

3. Open the code behind file for the new WebService1.aspx and change the using statements to:
using System;
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

4. Change the inheritance from System.Web.UI.Page to L3PageTemplate


5. Add two private members to the class:
private WebServiceController controller;
private DropDownList stateList;

6. In the OnInit event, instantiate the controller before the base OnInit method is called:
controller = new WebServiceController();

7. Add the private method PopulateDropDowns:


private void PopulateDropDowns()
{
SortedList states = controller.GetStates();

if (states != null && states.Count > 0)


{
ValidationManager.AddSuccess(states.Count + " values returned from web service.");

stateList.DataSource = states;
stateList.DataTextField = "value";
stateList.DataValueField = "key";
stateList.DataBind();
}
}

8. Add a call to PopulateDropDowns in the "if(!IsPostBack) of the OnPreRender event.


9. In CreateChildControls add the following after the call to base.CreateChildControls():
stateList = L3ControlFactory.CreateDropDown();

L3Form form = new L3Form();


form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList);

ValidationManager.AddInfo("This is an example of using a remote web service to populate a dropdown list.");

Controls.Add(L3Border.WrapControl(form, "Web Service Example 1", L3Icon.Application));


51
10. Save all files and browse the WebServices1.aspx

52
Source File Code 5.7: WebService1.aspx.cs
using System;
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

public partial class WebService1 : L3PageTemplate


{
#region Attributes

private WebServiceController controller;


private DropDownList stateList;

#endregion

#region Control Overrides

protected override void OnInit(EventArgs e)


{
controller = new WebServiceController();

base.OnInit(e);
EnsureChildControls();
}

protected override void OnPreRender(EventArgs e)


{
base.OnPreRender(e);

if (!IsPostBack)
{
PopulateDropDowns();
}
}

protected override void CreateChildControls()


{
base.CreateChildControls();

stateList = L3ControlFactory.CreateDropDown();

L3Form form = new L3Form();


form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList);
ValidationManager.AddInfo("This is an example of using a remote web service
to populate a dropdown list.");
Controls.Add(L3Border.WrapControl(form, "Web Service Example 1",
L3Icon.Application));
}

#endregion

#region Private Methods

private void PopulateDropDowns()


53
{
SortedList states = controller.GetStates();

if (states != null && states.Count > 0)


{
ValidationManager.AddSuccess(states.Count + " values returned from web
service.");

stateList.DataSource = states;
stateList.DataTextField = "value";
stateList.DataValueField = "key";
stateList.DataBind();
}
}
#endregion
}

54
Module 6: Populating a GridView with Web Service Data
Module Goal:
This module introduces one of the most heavily used web controls in Cornerstone, the L3GridView. We will
build a form that finds and displays all of the Rate Centers in a selected state and another form to display the
details of a selected Rate Center. To get to the data we need we will add code to expose additional methods and
objects from the TAI web service. We will also use some of the built in features of the Cornerstone L3GridView.

55
Procedure 6.1: Updating the TAI Service code with new methods
1. Open ITaiWebService.cs and add a method signature for FindAllRateCenter and FindOneRateCenter
with:
RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVO);
RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo);

2. Add a public static method to TaiWebServices for converting the objects coming back from the
FindAllRateCenter method to RateCenterVOs similar to what we did with the LocStateVOs with the
following:
public static RateCenterVO RateCenterObjectConverter(object obj)
{
return (RateCenterVO) obj;
}

3. Implement FindAllRateCenter and FindOneRateCenter in TaiWebService.cs with the method:


public RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVo)
{
return Array.ConvertAll((service as TAI_WebServices).findAllRateCenter(rateCenterVo), new
Converter<object, RateCenterVO>(RateCenterObjectConverter));
}

public RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo)


{
return (service as TAI_WebServices).findOneRateCenter(rateCenterVo);
}

4. Open TaiWebServiceStub and add a method to it for FindAllRateCenter, FindOneRateCenter, and


BuildRateCenterVO similar to what we did with LocStateVOs with:
public RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVo)
{
int numRcs = 50;
RateCenterVO[] rcs = new RateCenterVO[numRcs];

for (int i = 0; i < numRcs; i++)


{
rcs[i] = BuildRateCenterVO(i);
}

return rcs;
}

public RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo)


{
return BuildRateCenterVO(1);
}

RateCenterVO BuildRateCenterVO(int id)


{
RateCenterVO rateCenterVo = new RateCenterVO();
rateCenterVo.rcAbbrev = "rcAbbrev-" + id;
rateCenterVo.stateAbbrev = "stateAbbrev-" + id;
rateCenterVo.rateCenterEid = id;

56
rateCenterVo.lata = id;
rateCenterVo.level3Ocn = id;
rateCenterVo.lastUpdateDate = DateTime.Now.ToString();
rateCenterVo.lastUpdateUser = "User-" + id;
rateCenterVo.taxationClli = "taxCLLI-" + id;

return rateCenterVo;
}

5. In WebServiceController.cs add the method EmptyRateCenterVO like we did earlier with


EmptyLocStateVO:
public static RateCenterVO EmptyRateCenterVO
{
//The web service expects a null for "unset" integers, but .NET
//doesn't allow this. Compromise: Set INT fields equal to -1
//the service will read these as null
get
{
RateCenterVO retVO = new RateCenterVO();
retVO.level3Ocn = -1;
retVO.lata = -1;
retVO.rateCenterEid = -1;
retVO.tnCoverageOcn = -1;
retVO.sequenceLock = -1;

return retVO;
}
}

6. Add the public methods GetRateCentersForStateAbbreviation and GetRateCentersByEid to


WebServiceController.cs:
public RateCenterVO[] GetRateCentersForStateAbbreviation(string stateAbbrev)
{
RateCenterVO rateCenter = EmptyRateCenterVO;
rateCenter.stateAbbrev = stateAbbrev;
RateCenterVO[] rateCenterResults = webService.FindAllRateCenter(rateCenter);

return rateCenterResults;
}

public RateCenterVO GetRateCentersByEid(int eid)


{
RateCenterVO rateCenter = EmptyRateCenterVO;
rateCenter.rateCenterEid = eid;
RateCenterVO rateCenterResult = webService.FindOneRateCenter(rateCenter);

return rateCenterResult;
}

7. Save all files and build the solution.

57
Source File Code 6.1: ITaiWebServices.cs
using HelloWorld.Services.WebServices.TAI.Maint;

namespace HelloWorld.Services.WebServices
{
public interface ITaiWebService
{
LocStateVO[] FindAllLocState(LocStateVO locStateVO);
RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVO);
RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo);
}
}

Source File Code 6.1: TaiWebServices.cs


using System;
using System.Web.Services.Protocols;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.UDDIRegistry;

namespace HelloWorld.Services.WebServices
{
public class TaiWebService : ITaiWebService
{
private string serviceName = typeof(TAI_WebServices).Name;
private SoapHttpClientProtocol service;

public TaiWebService()
{
service = new TAI_WebServices();
IRegistry registry = RegistryManager.Load();
registry.Bind(serviceName, service);
}

#region ITaiWebService Members

public LocStateVO[] FindAllLocState(LocStateVO locStateVo)


{
return Array.ConvertAll((service as
TAI_WebServices).findAllLocState(locStateVo), new Converter<object,
LocStateVO>(LocStateObjectConverter));
}

public RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVo)


{
return Array.ConvertAll((service as
TAI_WebServices).findAllRateCenter(rateCenterVo), new Converter<object,
RateCenterVO>(RateCenterObjectConverter));
}

public RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo)


{
return (service as TAI_WebServices).findOneRateCenter(rateCenterVo);
}

#endregion

#region Converters

58
public static LocStateVO LocStateObjectConverter(object obj)
{
return (LocStateVO)obj;
}

public static RateCenterVO RateCenterObjectConverter(object obj)


{
return (RateCenterVO) obj;
}

#endregion
}
}

Source File Code 6.1: TaiWebServicesStub.cs


using System;
using HelloWorld.Services.WebServices;
using HelloWorld.Services.WebServices.TAI.Maint;

namespace HelloWorld.Services.Stubs
{
public class TaiWebServiceStub : ITaiWebService
{
#region ITaiWebService Members

public LocStateVO[] FindAllLocState(LocStateVO locStateVo)


{
int numStates = 50;
LocStateVO[] locStates = new LocStateVO[numStates];
for (int i = 0; i < numStates; i++)
{
locStates[i] = BuildLocStateVO(i);
}
return locStates;
}

public RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVo)


{
int numRcs = 50;
RateCenterVO[] rcs = new RateCenterVO[numRcs];

for (int i = 0; i < numRcs; i++)


{
rcs[i] = BuildRateCenterVO(i);
}

return rcs;
}

public RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo)


{
return BuildRateCenterVO(1);
}

#endregion

#region Helpers

LocStateVO BuildLocStateVO(int id)


{
59
LocStateVO locStateVo = new LocStateVO();
locStateVo.name = "Name-" + id;
locStateVo.abbrev = "Abbrev-" + id;
locStateVo.lastUpdateDate = DateTime.Now.ToString();
locStateVo.lastUpdateUser = "User-" + id;

return locStateVo;
}

RateCenterVO BuildRateCenterVO(int id)


{
RateCenterVO rateCenterVo = new RateCenterVO();
rateCenterVo.rcAbbrev = "rcAbbrev-" + id;
rateCenterVo.stateAbbrev = "stateAbbrev-" + id;
rateCenterVo.rateCenterEid = id;
rateCenterVo.lata = id;
rateCenterVo.level3Ocn = id;
rateCenterVo.lastUpdateDate = DateTime.Now.ToString();
rateCenterVo.lastUpdateUser = "User-" + id;
rateCenterVo.taxationClli = "taxCLLI-" + id;

return rateCenterVo;
}

#endregion
}
}

Source File Code 6.1: WebServiceController.cs


using System;
using System.Collections;
using HelloWorld.Services;
using HelloWorld.Services.WebServices;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.Web.WebControls.Validation;

namespace HelloWorld.Web.Controllers
{
public class WebServiceController
{
private ITaiWebService webService;

#region Constructors

public WebServiceController()
: this(CSTServicesFactory.Create<ITaiWebService>())
{
}

public WebServiceController(ITaiWebService webService)


{
this.webService = webService;
}

#endregion

#region Members
public SortedList GetStates()
{
try
60
{
LocStateVO[] locStates =
webService.FindAllLocState(EmptyLocStateVO);

SortedList stateList = new SortedList();

foreach (LocStateVO locState in locStates)


{
stateList.Add(locState.abbrev,locState.name);
}

return stateList;
}
catch (Exception ex)
{
ValidationManager.AddFailure("GetStateNameAbbreviations failed: " +
ex.Message);
return new SortedList();
}
}

public RateCenterVO[] GetRateCentersForStateAbbreviation(string stateAbbrev)


{
RateCenterVO rateCenter = EmptyRateCenterVO;

rateCenter.stateAbbrev = stateAbbrev;

RateCenterVO[] rateCenterResults =
webService.FindAllRateCenter(rateCenter);

return rateCenterResults;
}

public RateCenterVO GetRateCentersByEid(int eid)


{
RateCenterVO rateCenter = EmptyRateCenterVO;
rateCenter.rateCenterEid = eid;
RateCenterVO rateCenterResult = webService.FindOneRateCenter(rateCenter);

return rateCenterResult;
}

#endregion

#region Helpers
public static LocStateVO EmptyLocStateVO
{
//The web service expects a null for "unset" integers, but .NET
//doesn't allow this. Compromise: Set INT fields equal to -1
//the service will read these as null
get
{
LocStateVO retVO = new LocStateVO();
retVO.sequenceLock = -1;
return retVO;
}
}

public static RateCenterVO EmptyRateCenterVO


{

61
//The web service expects a null for "unset" integers, but .NET
//doesn't allow this. Compromise: Set INT fields equal to -1
//the service will read these as null
get
{
RateCenterVO retVO = new RateCenterVO();
retVO.level3Ocn = -1;
retVO.lata = -1;
retVO.rateCenterEid = -1;
retVO.tnCoverageOcn = -1;
retVO.sequenceLock = -1;

return retVO;
}
}

#endregion
}
}

62
Procedure 6.2: Creating the GridViewFactory and a GridView definition
1. Add a reference to Cornerstone.Web.dll in the HelloWorld.Common project.
2. Create a new class file in the HelloWorld.Common project called HWGridViewFactory.cs
3. Replace all the code in the HWGridViewFactory.cs with the following:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using Level3.Cornerstone.Web.WebControls;

namespace HelloWorld.Common
{
/// <summary>
/// Creates data grid defs from the xml file GridDefinitions.xml
/// </summary>
public static class HWGridViewFactory
{
#region private members

public const string GridDefinitionFile = "/App_LocalResources/HWGridDefinitions.xml";


private static GridViewDefinitionFactory factory;

#endregion

public static GridViewDefinition Create(string name)


{
if (factory == null)
{
Stream stream = File.OpenRead(HttpContext.Current.Server.MapPath("") + GridDefinitionFile);
factory = new GridViewDefinitionFactory(stream, HWValueMapper.Instance);
}

return factory.Create(name);
}
}
}

4. Create a new XML document in the HelloWorld web site under App_LocalResources called
HWGridDefinitions.xml.
5. Add the following xml to HWGridDefinitions:
<Definitions xmlns="http://www.level3.com/Cornerstone/GridDefinitionSchema.xsd">

<Grid name="ratecentergriddef" dataSourceType="Dto" showFooter="true" >


<Columns>
<Column dataFieldKey="rateCenterEid" />
<Column dataFieldKey="rcAbbrev" />
<Column dataFieldKey="stateAbbrev" />
<Column dataFieldKey="taxationClli" />
<Column dataFieldKey="level3Ocn" />
<Column dataFieldKey="lata" />
</Columns>
</Grid>

63
</Definitions>
6. Add the following values to HWValueMapper.xml under the Values element:
<ValueItem key="submit" presentationValue="Submit" />

<!-- Datagrid Columns -->


<ValueItem key="stateabbrev" dtoValue="stateAbbrev" presentationValue="State" />
<ValueItem key="rcabbrev" dtoValue="rcAbbrev" presentationValue="Rate Center" />
<ValueItem key="ratecentereid" dtoValue="rateCenterEid" presentationValue="EID" />
<ValueItem key="taxationclli" dtoValue="taxationClli" presentationValue="Tax CLLI" />
<ValueItem key="level3ocn" dtoValue="level3Ocn" presentationValue="OCN" />
<ValueItem key="lata" dtoValue="lata" presentationValue="LATA" />

64
Source File Code 6.2: HWGridViewFactory.cs
using System.IO;
using System.Web;
using Level3.Cornerstone.Web.WebControls;

namespace HelloWorld.Common
{
/// <summary>
/// Creates data grid defs from the xml file GridDefinitions.xml
/// </summary>
public static class HWGridViewFactory
{
#region private members

public const string GridDefinitionFile =


"/App_LocalResources/HWGridDefinitions.xml";
private static GridViewDefinitionFactory factory;

#endregion

public static GridViewDefinition Create(string name)


{
if (factory == null)
{
Stream stream = File.OpenRead(HttpContext.Current.Server.MapPath("")
+ GridDefinitionFile);
factory = new GridViewDefinitionFactory(stream,
HWValueMapper.Instance);
}

return factory.Create(name);
}
}
}

Source File Code 6.2: HWGridDefinitions.xml


<?xml version="1.0" encoding="utf-8" ?>
<Definitions xmlns="http://www.level3.com/Cornerstone/GridDefinitionSchema.xsd">

<Grid name="ratecentergriddef" dataSourceType="Dto" showFooter="true" >


<Columns>
<Column dataFieldKey="rateCenterEid" />
<Column dataFieldKey="rcAbbrev" />
<Column dataFieldKey="stateAbbrev" />
<Column dataFieldKey="taxationClli" />
<Column dataFieldKey="level3Ocn" />
<Column dataFieldKey="lata" />
</Columns>
</Grid>

</Definitions>

65
Procedure 6.3: Creating the Rate Center search page
1. Add a new web page called "WebService2" using the CornerstonePage template.
2. Open WebService2.aspx.cs and set the following "using" statements:
using System;
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Services.WebServices.TAI.Maint;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

3. Add the following member variables:


private bool autoCollapseCriteria = true;
private WebServiceController controller;
private DropDownList stateList;
private Button submitButton;
private L3GridView resultsGrid;
private L3Border criteriaBorder;
private L3Border resultsBorder;

4. In OnInit before the base.OnInit is called:


controller = new WebServiceController();

5. In OnPreRender add the following after the base.OnPreRender is called (PopulateDropDowns will be
added in a later step):
if (!IsPostBack)
{
PopulateDropDowns();
resultsBorder.Visible = false;
}

6. In CreateChildControls add the following after base.CreateChildControls is called:


stateList = L3ControlFactory.CreateDropDown();
L3Form form = new L3Form();
form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList);

L3ButtonPanel bp = new L3ButtonPanel();


submitButton = L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("submit"));
submitButton.Click += new EventHandler(submitButton_Click);
bp.AddRightControl(submitButton);

criteriaBorder = L3Border.WrapControl(form, "Web Service Example 2", L3Icon.Application, bp);

GridViewDefinition rateCenterGridView = HWGridViewFactory.Create("ratecentergriddef");

resultsGrid = L3GridView.Create(rateCenterGridView, true);


resultsBorder = L3Border.WrapControl(resultsGrid, "Rate Center Results");

ValidationManager.AddInfo("This is an example of a basic search using a remote web service.");

66
Controls.Add(criteriaBorder);
Controls.Add(resultsBorder);

7. In the "Events" region add the following event:


void submitButton_Click(object sender, EventArgs e)
{
try
{
RateCenterVO[] rateCenters = controller.GetRateCentersForStateAbbreviation(stateList.SelectedValue);
PopulateResultsGrid(rateCenters);
}
catch (Exception ex)
{
UserMessageManager.AddFailure("An error occurred getting rate centers: " + ex.Message);
}
}

8. In the "Private Methods" region add the following two methods:


private void PopulateResultsGrid(RateCenterVO[] rateCenters)
{
if (rateCenters.Length == 0)
{
resultsBorder.Visible = false;
}
else
{
resultsBorder.Visible = true;
resultsGrid.Populate(rateCenters);

if (autoCollapseCriteria)
{
criteriaBorder.Collapsed = true;
}
}
}

private void PopulateDropDowns()


{
SortedList states = controller.GetStates ();

if (states != null && states.Count > 0)


{
stateList.DataSource = states;
stateList.DataTextField = "value";
stateList.DataValueField = "key";
stateList.DataBind();
}
}

9. Save all files rebuild the solution and browse the WebService2.aspx page.

67
Source File Code 6.3: WebService2.xml
using System;
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Services.WebServices.TAI.Maint;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

/// <summary>
/// Summary description for WebService2
/// Cornerstone Enabled Web Form
/// </summary>
public partial class WebService2 : L3PageTemplate
{
#region Attributes
private bool autoCollapseCriteria = true;

private WebServiceController controller;


private DropDownList stateList;
private Button submitButton;
private L3GridView resultsGrid;
private L3Border criteriaBorder;
private L3Border resultsBorder;

#endregion

#region Control Overrides

protected override void OnInit(EventArgs e)


{
controller = new WebServiceController();

base.OnInit(e);
EnsureChildControls();
}

protected override void CreateChildControls()


{
base.CreateChildControls();

stateList = L3ControlFactory.CreateDropDown();
L3Form form = new L3Form();
form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList);

L3ButtonPanel bp = new L3ButtonPanel();


submitButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("submit"));
submitButton.Click += new EventHandler(submitButton_Click);
bp.AddRightControl(submitButton);

criteriaBorder = L3Border.WrapControl(form, "Web Service Example 2",


L3Icon.Application, bp);

GridViewDefinition rateCenterGridView =
HWGridViewFactory.Create("ratecentergriddef");

68
resultsGrid = L3GridView.Create(rateCenterGridView, true);
resultsBorder = L3Border.WrapControl(resultsGrid, "Rate Center Results");

ValidationManager.AddInfo("This is an example of a basic search using a


remote web service.");

Controls.Add(criteriaBorder);
Controls.Add(resultsBorder);
}

protected override void OnPreRender(EventArgs e)


{
base.OnPreRender(e);

if (!IsPostBack)
{
PopulateDropDowns();
resultsBorder.Visible = false;
}

#endregion

#region Events
void submitButton_Click(object sender, EventArgs e)
{
try
{
RateCenterVO[] rateCenters =
controller.GetRateCentersForStateAbbreviation(stateList.SelectedValue);
PopulateResultsGrid(rateCenters);
}
catch (Exception ex)
{
ValidationManager.AddFailure("An error occurred getting rate centers: " +
ex.Message);
}
}

#endregion

#region Private Methods


private void PopulateResultsGrid(RateCenterVO[] rateCenters)
{
if (rateCenters.Length == 0)
{
resultsBorder.Visible = false;
}
else
{
resultsBorder.Visible = true;
resultsGrid.Populate(rateCenters);

if (autoCollapseCriteria)
{
criteriaBorder.Collapsed = true;
}
}
}

69
private void PopulateDropDowns()
{
SortedList states = controller.GetStates();

if (states != null && states.Count > 0)


{
stateList.DataSource = states;
stateList.DataTextField = "value";
stateList.DataValueField = "key";
stateList.DataBind();
}
}

#endregion
}

70
Procedure 6.4: Adding export and paging to the rate center grid
1. Open WebService2.aspx.cs.
2. In the CreateChildControls the line
resultsGrid = L3GridView.Create(rateCenterGridView, true);
to
resultsGrid = L3GridView.Create(rateCenterGridView, true, 10);

3. Save and browse the page. The grid will now have a paging bar at the top. Each page will contain 10
rows.
4. Add the following statement:
resultsGrid.ExportEnabled = true;

5. Save and browse the page. Notice the grid now has an export to Excel option.
6. Add the statements:
resultsGrid.CheckBoxColumnDataField = "rateCenterEid";
resultsGrid.AutoGenerateCheckBoxColumn = true;

7. Save and browse the page. The grid will now have a checkbox column and a "Export Selected" option.
Note: The same results can be obtained by removing these two statements and adding
"checkBoxDataFieldKey="rateCenterEid" to the GridView definition in HWGridDefinitions.

71
Procedure 6.5: Creating the Rate Center detail page
1. Open HWGridDefinitions.xml and add the following element to the definition of the "ratecentergriddef"
which adds an action icon to the GridView and defines which page the request will be routed to when
the user clicks the action icon:
<Actions>
<RedirectAction icon="PageGo" pageId="rateCenterDetails" toolTipKey="ratecenterdetails">
<Parameter dataFieldKey="rateCenterEid" id="ratecentereid"/>
</RedirectAction>
</Actions>

2. If not already there, add the property "checkBoxDataFieldKey="rateCenterEid" to "ratecentergriddef"


3. Add the following item to HWValueMapper.xml:
<!-- Tooltips -->
<ValueItem key="ratecenterdetails" presentationValue="View Rate Center Details" />

4. Create a new xml document called "Flow.xml" in the App_LocalResources folder of the HelloWorld
web site and add the following element:
<Flow>
<FlowItem pageId="rateCenterDetails" file="RateCenterDetails" pageTitle="RateCenterDetails"/>
</Flow>

5. Right click the HelloWorld web site and add a Site Map. Leave the name as the default Web.sitemap.
6. Replace the blank siteMapNode with:
<siteMapNode url="Default.aspx" title="Home" description="">
<siteMapNode title="Web Service Calls">
<siteMapNode url="WebService1.aspx" title="Web Service 1" description="" />
<siteMapNode url="WebService2.aspx" title="Web Service 2" description="" />
</siteMapNode>
<siteMapNode title="Detail Pages">
<siteMapNode url="RateCenterDetails.aspx" title="Rate Center Details" description="" />
</siteMapNode>
</siteMapNode>

7. Add a new web page called "RateCenterDetails.aspx" using the CornerstonePage template.
8. Open RateCenterDetails.aspx.cs and set the following "using" statements:
using System;
using HelloWorld.Common;
using HelloWorld.Services.WebServices.TAI.Maint;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

9. Add the following member variables:


private WebServiceController controller = new WebServiceController();

10. In CreateChildControls add the following after base.CreateChildControls is called:


L3Form form = new L3Form();

72
try
{
int eid = Int32.Parse(Request.QueryString["ratecentereid"]);

RateCenterVO rateCenter = controller.GetRateCentersByEid(eid);

form.AddRow(HWValueMapper.Instance.GetLabelValue("ratecentereid"),
L3ControlFactory.CreateLabel(rateCenter.rateCenterEid.ToString()));
form.AddRow(HWValueMapper.Instance.GetLabelValue("rcabbrev"),
L3ControlFactory.CreateLabel(rateCenter.rcAbbrev));
form.AddRow(HWValueMapper.Instance.GetLabelValue("stateabbrev"),
L3ControlFactory.CreateLabel(rateCenter.stateAbbrev));
form.AddRow(HWValueMapper.Instance.GetLabelValue("taxationclli"),
L3ControlFactory.CreateLabel(rateCenter.taxationClli));
form.AddRow(HWValueMapper.Instance.GetLabelValue("level3ocn"),
L3ControlFactory.CreateLabel(rateCenter.level3Ocn.ToString()));
form.AddRow(HWValueMapper.Instance.GetLabelValue("lata"),
L3ControlFactory.CreateLabel(rateCenter.lata.ToString()));
}
catch (Exception ex)
{
ValidationManager.AddFailure("Failed to find rate center.");
}

L3ButtonPanel bp = new L3ButtonPanel();


bp.AddLeftControl(L3ControlFactory.CreateBackButton());

ValidationManager.AddInfo("This is an example of a details screen.");

Controls.Add(L3Border.WrapControl(form, "Rate Center Details", L3Icon.PageDetails, bp));

11. Save all files, browse WebService2.aspx, get the Rate Centers for a state and select the Rate Center
Details icon in the grid.

73
Source File Code 6.5: HWGridDefinitions.xml
<?xml version="1.0" encoding="utf-8" ?>
<Definitions xmlns="http://www.level3.com/Cornerstone/GridDefinitionSchema.xsd">

<Grid name="ratecentergriddef" dataSourceType="Dto"


checkBoxDataFieldKey="rateCenterEid" showFooter="true" >
<Columns>
<Column dataFieldKey="rateCenterEid" />
<Column dataFieldKey="rcAbbrev" />
<Column dataFieldKey="stateAbbrev" />
<Column dataFieldKey="taxationClli" />
<Column dataFieldKey="level3Ocn" />
<Column dataFieldKey="lata" />
</Columns>
<Actions>
<RedirectAction icon="PageGo" pageId="rateCenterDetails"
toolTipKey="ratecenterdetails">
<Parameter dataFieldKey="rateCenterEid" id="ratecentereid"/>
</RedirectAction>
</Actions>
</Grid>

</Definitions>

Source File Code 6.5: Web.sitemap


<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Default.aspx" title="Home" description="">
<siteMapNode title="Web Service Calls">
<siteMapNode url="WebService1.aspx" title="Web Service 1" description="" />
<siteMapNode url="WebService2.aspx" title="Web Service 2" description="" />
</siteMapNode>
<siteMapNode title="Detail Pages">
<siteMapNode url="RateCenterDetails.aspx" title="Rate Center Details"
description="" />
</siteMapNode>
</siteMapNode>
</siteMap>

Source File Code 6.5: RateCenterDetails.aspx.cs


using System;
using HelloWorld.Common;
using HelloWorld.Services.WebServices.TAI.Maint;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

/// <summary>
/// Summary description for RateCenterDetails
/// Cornerstone Enabled Web Form
/// </summary>
public partial class RateCenterDetails : L3PageTemplate
{
#region Attributes
private WebServiceController controller = new WebServiceController();
#endregion

74
#region Control Overrides

protected override void OnInit(EventArgs e)


{
base.OnInit(e);
EnsureChildControls();
}

protected override void CreateChildControls()


{
base.CreateChildControls();

L3Form form = new L3Form();

try
{
int eid = Int32.Parse(Request.QueryString["ratecentereid"]);

RateCenterVO rateCenter = controller.GetRateCentersByEid(eid);

form.AddRow(HWValueMapper.Instance.GetLabelValue("ratecentereid"),
L3ControlFactory.CreateLabel(rateCenter.rateCenterEid.ToStrin
g()));
form.AddRow(HWValueMapper.Instance.GetLabelValue("rcabbrev"),
L3ControlFactory.CreateLabel(rateCenter.rcAbbrev));
form.AddRow(HWValueMapper.Instance.GetLabelValue("stateabbrev"),
L3ControlFactory.CreateLabel(rateCenter.stateAbbrev));
form.AddRow(HWValueMapper.Instance.GetLabelValue("taxationclli"),
L3ControlFactory.CreateLabel(rateCenter.taxationClli));
form.AddRow(HWValueMapper.Instance.GetLabelValue("level3ocn"),
L3ControlFactory.CreateLabel(rateCenter.level3Ocn.ToString()));
form.AddRow(HWValueMapper.Instance.GetLabelValue("lata"),
L3ControlFactory.CreateLabel(rateCenter.lata.ToString()));
}
catch (Exception ex)
{
ValidationManager.AddFailure("Failed to find rate center.");
}

L3ButtonPanel bp = new L3ButtonPanel();


bp.AddLeftControl(L3ControlFactory.CreateBackButton());

ValidationManager.AddInfo("This is an example of a details screen.");

Controls.Add(L3Border.WrapControl(form, "Rate Center Details",


L3Icon.PageDetails, bp));
}

protected override void OnPreRender(EventArgs e)


{
base.OnPreRender(e);
}

#endregion
}

75
Module 7: HelloWorld Base Page and Using the Cornerstone SearchControl
Module Goal:
This module begins by building a base page that we can use as a base for all subsequent pages. We will
instantiate objects in the base that are used by nearly every page in the application such as the HWValueMapper.
Next we will build the structure for and use another heavily used control in Cornerstone, the SearchControl.
There are three steps to using the search control: create a dedicated search control based on the Cornerstone
SearchControl, create a controller for the search control, add the control to the page.

76
Procedure 7.1: Creating the HelloWorld base page
1. Right click the HelloWorld web site and select "Add ASP.NET Folder" then App_Code.
2. Add a new class in the App_Code folder called HWPageBase.cs.
3. Make this class public abstract and inherit "L3PageTemplate":
public abstract class HWPageBase : L3PageTemplate

4. Add the following using statements:


using HelloWorld.Common;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Web.WebControls;

5. Delete the default constructor.


6. Add the property:
protected static IValueMapper Mapper
{
get { return HWValueMapper.Instance; }
}

7. From now on our solutions pages will inherit from this base page class and will automatically have an
instance of the HWValueMapper available to it. Other uses for this base class include logging, session
management, and navigation..

77
Source File Code 7.1: HWPageBase.cs
using HelloWorld.Common;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Web.WebControls;

/// <summary>
/// Base page class for the HelloWorld web application
/// </summary>
public abstract class HWPageBase : L3PageTemplate
{
protected static IValueMapper Mapper
{
get { return HWValueMapper.Instance; }
}
}

78
Procedure 7.2: Creating the dedicated search control
1. Create a folder called “WebControls” in the App_Code folder of the HelloWorld web site.
2. Create a folder called “CriteriaControls” in the “WebControls” folder.
3. Create a class file called “RateCenterSearchCriteriaControl.cs” in the WebControls folder.
4. Make the class public and delete the default constructor.
5. Add the using statements:
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web;
using Level3.Cornerstone.Web.WebControls;

6. Make the class inherit from the Cornerstone base class SearchCriteriaControl
7. Add the following private variables:
private L3ListBox stateList;
private TextBox rcAbbrevTextBox;
private TextBox lataTextBox;
private IValueMapper mapper = CSTHWValueMapper.Instance;

8. Add a private method called Populate with:


private void Populate()
{
EnsureChildControls();
WebServiceController controller = new WebServiceController();
SortedList stateNames = controller.GetStates();

stateList.DataSource = stateNames;
stateList.DataTextField = "value";
stateList.DataValueField = "key";
stateList.DataBind();
}

9. Override the CreateChildControls:


protected override void CreateChildControls()
{
base.CreateChildControls();

stateList = L3ControlFactory.CreateListBox();
rcAbbrevTextBox = new L3TextBox();
lataTextBox = new L3TextBox();

L3Form form = new L3Form();


form.AddRow(mapper.GetLabelValue("stateabbrev"), stateList);
form.AddRow(mapper.GetLabelValue("rcabbrev"), rcAbbrevTextBox);
form.AddRow(mapper.GetLabelValue("lata"), lataTextBox);

Controls.Add(form);

if (!Page.IsPostBack)

79
{
Populate();
}
}

10. Override the Criteria property with:


public override SearchCriteria Criteria
{
get
{
SearchCriteria criteria = new SearchCriteria();

criteria.Add("stateabbrev", SearchCriteriaValue.Create(stateList.SelectedValue));
criteria.Add("rcabbrev", SearchCriteriaValue.Create(rcAbbrevTextBox.Text));
criteria.Add("lata", SearchCriteriaValue.Create(lataTextBox.Text));

return criteria;
}
set
{
WebUtil.SelectItemsByValue(stateList, value["stateabbrev"].Value as string);
rcAbbrevTextBox.Text = (string)value["rcabbrev"].Value;
lataTextBox.Text = (string)value["lata"].Value;
}
}

11. Save and build the solution.

80
Source File Code 7.2: RateCenterSearchCriteriaControl.cs
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web;
using Level3.Cornerstone.Web.WebControls;

/// <summary>
/// Summary description for RateCenterSearchCriteriaControl
/// </summary>
public class RateCenterSearchCriteriaControl : SearchCriteriaControl
{
private L3ListBox stateList;
private TextBox rcAbbrevTextBox;
private TextBox lataTextBox;
private IValueMapper mapper = HelloWorld.Common.HWValueMapper.Instance;

protected override void CreateChildControls()


{
base.CreateChildControls();

stateList = L3ControlFactory.CreateListBox();
rcAbbrevTextBox = new L3TextBox();
lataTextBox = new L3TextBox();

L3Form form = new L3Form();


form.AddRow(mapper.GetLabelValue("stateabbrev"), stateList);
form.AddRow(mapper.GetLabelValue("rcabbrev"), rcAbbrevTextBox);
form.AddRow(mapper.GetLabelValue("lata"), lataTextBox);

Controls.Add(form);

if (!Page.IsPostBack)
{
Populate();
}
}

public override SearchCriteria Criteria


{
get
{
SearchCriteria criteria = new SearchCriteria();

criteria.Add("stateabbrev",
SearchCriteriaValue.Create(stateList.SelectedValue));
criteria.Add("rcabbrev",
SearchCriteriaValue.Create(rcAbbrevTextBox.Text));
criteria.Add("lata", SearchCriteriaValue.Create(lataTextBox.Text));

return criteria;
}
set
{
WebUtil.SelectItemsByValue(stateList, value["stateabbrev"].Value as
string);
rcAbbrevTextBox.Text = (string)value["rcabbrev"].Value;
81
lataTextBox.Text = (string)value["lata"].Value;
}
}

private void Populate()


{
EnsureChildControls();
WebServiceController controller = new WebServiceController();
SortedList stateNames = controller.GetStates();

stateList.DataSource = stateNames;
stateList.DataTextField = "value";
stateList.DataValueField = "key";
stateList.DataBind();
}
}

82
Procedure 7.3: Creating the search controller
1. Add a reference to Level3.Cornerstone.Data.dll to the HelloWorld.Web.Controllers project.
2. Add the following method to WebServiceController.cs in the HelloWorldWebControllers project:
public RateCenterVO[] GetRateCentersByExample(RateCenterVO criteria)
{
RateCenterVO rateCenter = EmptyRateCenterVO ;

if (criteria.stateAbbrev != null)
{
rateCenter.stateAbbrev = criteria.stateAbbrev;
}

if (criteria.rcAbbrev != null)
{
rateCenter.rcAbbrev = criteria.rcAbbrev;
}

if (criteria.lata != -1)
{
rateCenter.lata = criteria.lata;
}

RateCenterVO[] rateCenterResults = webService.FindAllRateCenter(rateCenter);

return rateCenterResults;
}

3. Create the class RateCenterSearchController.cs in the HelloWorld.Web.Controllers project.


4. Add the using statements:
using System;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web.WebControls;

5. Make the class public.


6. Add the private member variable:
private WebServiceController controller;

7. Add the two public contructors:


public RateCenterSearchController() : this(new WebServiceController())
{
}

public RateCenterSearchController(WebServiceController controller)


{
this.controller = controller;
}

8. Implement the DoSearch method with:


protected override SearchResult DoSearch(SearchCriteria criteria)
{
// This is a data mapping step and could be implemented as a dedicated data mapping routine.
83
RateCenterVO example = WebServiceController. BuildEmptyRateCenterVO();

if (criteria["rcabbrev"] != null && !String.IsNullOrEmpty((string)criteria["rcabbrev"].Value))


{
example.rcAbbrev = (string) criteria["rcabbrev"].Value;
}

if (criteria["stateabbrev"] != null && !String.IsNullOrEmpty((string)criteria["stateabbrev"].Value))


{
example.stateAbbrev = (string)criteria["stateabbrev"].Value;
}

if (criteria["lata"] != null && !String.IsNullOrEmpty((string)criteria["lata"].Value))


{
example.lata = Int32.Parse((string)criteria["lata"].Value);
}

RateCenterVO[] rateCenterResponses = controller.GetRateCentersByExample(example);

SearchResult result = new SearchResult(rateCenterResponses);


return result;
}

9. Save all files and rebuild the solution.

84
Source File Code 7.3: RateCenterSearchController.cs
using System;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web.WebControls;

namespace HelloWorld.Web.Controllers
{
public class RateCenterSearchController : SearchController
{
private WebServiceController controller;

public RateCenterSearchController()
: this(new WebServiceController())
{}

public RateCenterSearchController(WebServiceController controller)


{
this.controller = controller;
}

protected override SearchResult DoSearch(SearchCriteria criteria)


{
// This is a data mapping step and could be implemented as a dedicated
data mapping routine.
RateCenterVO example = WebServiceController.EmptyRateCenterVO;

if (criteria["rcabbrev"] != null && !


String.IsNullOrEmpty((string)criteria["rcabbrev"].Value))
{
example.rcAbbrev = (string)criteria["rcabbrev"].Value;
}

if (criteria["stateabbrev"] != null && !


String.IsNullOrEmpty((string)criteria["stateabbrev"].Value))
{
example.stateAbbrev = (string)criteria["stateabbrev"].Value;
}

if (criteria["lata"] != null && !


String.IsNullOrEmpty((string)criteria["lata"].Value))
{
example.lata = Int32.Parse((string)criteria["lata"].Value);
}

RateCenterVO[] rateCenterResponses =
controller.GetRateCentersByExample(example);

SearchResult result = new SearchResult(rateCenterResponses);


return result;
}
}
}

85
Procedure 7.4: Creating the search page with the RateCenterSearchCriteriaControl
1. Add a new Cornerstone web page to the HelloWorld web site called WebService3.
2. Open WebService3.aspx.cs and change the inheritence from L3PageTemplate to HWPageBase.
3. Set the using statements to:
using System;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

4. Add the private member variables:


private SearchCriteriaControl criteriaControl;
private GridViewDefinition gridDefinition;
private SearchController searchController;

5. Add the following to CreateChildControls after the base CreateChildControls is called:


criteriaControl = new RateCenterSearchCriteriaControl();
gridDefinition = HWGridViewFactory.Create("ratecentergriddef");

searchController = new RateCenterSearchController();

SearchControl searchControl = new SearchControl(criteriaControl, searchController, gridDefinition);

ValidationManager.AddInfo("Web service search example using the search control.");


Controls.Add(searchControl);

6. Save and browse WebService3.aspx.

86
Source File Code 7.4: WebService3.aspx.cs
using System;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

/// <summary>
/// Summary description for WebService3
/// Cornerstone Enabled Web Form
/// </summary>
public partial class WebService3 : HWPageBase
{
#region Attributes
private SearchCriteriaControl criteriaControl;
private GridViewDefinition gridDefinition;
private SearchController searchController;
#endregion

#region Control Overrides

protected override void OnInit(EventArgs e)


{
base.OnInit(e);
EnsureChildControls();
}

protected override void CreateChildControls()


{
base.CreateChildControls();

criteriaControl = new RateCenterSearchCriteriaControl();


gridDefinition = HWGridViewFactory.Create("ratecentergriddef");

searchController = new RateCenterSearchController();

SearchControl searchControl = new SearchControl(criteriaControl,


searchController, gridDefinition);

ValidationManager.AddInfo("Web service search example using the search


control.");
Controls.Add(searchControl);
}

protected override void OnPreRender(EventArgs e)


{
base.OnPreRender(e);

if (!Page.IsPostBack)
{
}
}

#endregion
}

87
Module 8: Consuming Data from a Database
Module Goal:
In this module we build a search page using the same technique as the last module except the data will come
directly from a database instead of from a web service. The database we query is the Unified Auditing database
which is used to track web service calls from one IT system to another.

88
Procedure 8.1: Adding a datasource and creating the DAO
1. Open web.config and add the following element to the <connectionStrings> element:
<add name="INFSENV1" connectionString="Data Source=INFSENV1;User ID=aud_user; Password=aud_user;
pooling=true;" providerName="System.Data.OracleClient"/>

2. Add a reference to Level3.Cornerstone.Data.dll in the HelloWorld.Services project.


3. Add a project reference to the HelloWorld.Common project in the HelloWorldServices project.
4. Create a new folder in the HelloWorld.Services project called “DataAccess”.
5. Add a new class in the DataAccess folder called “UnifiedAuditingDao” and make it public.
6. Add the using statements:
using System.Data;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Data;

7. Create the private member variables:


private L3Database db;
private readonly string tableName = "AUDIT_SERVICE";

8. Create the two constructors:


public UnifiedAuditingDao() : this(new L3Database("INFSENV1"))
{
}

public UnifiedAuditingDao(L3Database db)


{
this.db = db;
}

9. Add the two public methods:


public SearchResult Search(SearchCriteria searchCriteria)
{
return Search(searchCriteria, tableName, HelloWorld.Common.HWValueMapper.Instance, false);
}

public SearchResult Search(SearchCriteria searchCriteria, string table, IValueMapper mapper, bool createIds)
{
SearchResult result = new SearchResult();

DataSet dataSet = db.ExecuteDataSet(table, searchCriteria, mapper);

if (createIds)
{
DataUtil.AddIdColumn(dataSet.Tables[0]);
}

result.Data = dataSet;
result.TotalRows = dataSet.Tables[0].Rows.Count;

return result;
}

89
10. Save and build the HelloWorld.Services project.

90
Source File Code 8.1: UnifiedAuditingDao.cs
using System.Data;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Data;

namespace HelloWorld.Services.DataAccess
{
public class UnifiedAuditingDao
{
private L3Database db;
private readonly string tableName = "AUDIT_SERVICE";

public UnifiedAuditingDao() : this(new L3Database("INFSENV1"))


{
}

public UnifiedAuditingDao(L3Database db)


{
this.db = db;
}

public SearchResult Search(SearchCriteria searchCriteria)


{
return Search(searchCriteria, tableName,
HelloWorld.Common.HWValueMapper.Instance, false);
}

public SearchResult Search(SearchCriteria searchCriteria, string table,


IValueMapper mapper, bool createIds)
{
SearchResult result = new SearchResult();

DataSet dataSet = db.ExecuteDataSet(table, searchCriteria, mapper);

if (createIds)
{
DataUtil.AddIdColumn(dataSet.Tables[0]);
}

result.Data = dataSet;
result.TotalRows = dataSet.Tables[0].Rows.Count;

return result;
}
}
}

91
Procedure 8.2: Creating the UnifiedAuditingSearchController, gridview definition,
UnifiedAuditingSearchCriteriaControl, and search page
(Note: The steps to build these files have been covered in Procedure 7 so the whole contents of each file will be
listed here and not built up in steps.)
1. Add a reference to Level3.Cornerstone.Common.dll, System.Web, and HelloWorld.Common to the
HelloWorld.Web.Controllers project.
2. Create the class UnifiedAuditingSearchController in the HelloWorld.Web.Controllers project and
add/change the code to:
using System;
using System.Data;
using System.Web;
using HelloWorld.Common;
using HelloWorld.Services.DataAccess;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Web.WebControls.Validation;

namespace HelloWorld.Web.Controllers
{
public class UnifiedAuditingSearchController : SearchController
{
#region Class Attributes

private readonly IValueMapper mapper = HWValueMapper.Instance;

private readonly UnifiedAuditingDao dao;

#endregion

#region Constructors

public UnifiedAuditingSearchController()
{
dao = new UnifiedAuditingDao();
}

#endregion

protected override SearchResult DoSearch(SearchCriteria searchCriteria)


{
SearchResult results = new SearchResult();
try
{
results = dao.Search(searchCriteria);
}
catch (Exception ex)
{
ValidationManager.AddFailure(ex.Message);
}

return FormatXmlFields(results);
}

private SearchResult FormatXmlFields(SearchResult result)


{
92
DataSet dataSet = result.Data;

if (dataSet.Tables.Count > 0)
{
DataTable dataTable = dataSet.Tables[0];

foreach (DataRow resultRow in dataTable.Rows)


{
string requestXml = resultRow["REQUEST_DATA"].ToString();
resultRow["REQUEST_DATA"] = HttpUtility.HtmlEncode(requestXml);

string responseXml = resultRow["RESPONSE_DATA"].ToString();


resultRow["RESPONSE_DATA"] = HttpUtility.HtmlEncode(responseXml);
}
}

return result;
}
}
}

3. Add the following GridView definition to HWGridDefinitions.xml in the HelloWorld web site:
<Grid name="unifiedauditinggriddef" dataSourceType="Database" showFooter="true" >
<Columns>
<Column dataFieldKey="auditserviceid" />
<Column dataFieldKey="correlationid" />
<Column dataFieldKey="audittimestamp" />
<Column dataFieldKey="sourceapplication" />
<Column dataFieldKey="operationname" />
<Column dataFieldKey="requestdata" characterLength="30" />
<Column dataFieldKey="responsedata" characterLength="30" />
<Column dataFieldKey="errorcode" />
<Column dataFieldKey="errormessage" characterLength="20"/>
</Columns>
</Grid>

4. Add the class “UnifiedAuditingSearchCriteriaControl” to the HelloWorld web site under the App_Code
WebControlsCriteriaControls folder and add/change its code to:
using System.Web.UI.WebControls;
using HelloWorld.Common;
using Level3.Cornerstone.Common;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web;
using Level3.Cornerstone.Web.WebControls;

/// <summary>
/// Summary description for UnifiedAuditingSearchCriteriaControl
/// </summary>
public class UnifiedAuditingSearchCriteriaControl : SearchCriteriaControl
{
private TextBox auditServiceIdTextBox;
private DateRangeControl auditTimestampDateRange;
private ListBox sourceApplicationListBox;
private TextBox operationNameTextBox;
private TextBox requestDataTextBox;
private TextBox responseDataTextBox;
93
private TextBox classNameTextBox;
private TextBox correlationIdTextBox;
private TextBox errorCodeTextBox;
private TextBox errorMessageTextBox;

private IValueMapper mapper = HWValueMapper.Instance;

#region Control Overrides

protected override void CreateChildControls()


{
base.CreateChildControls();

auditServiceIdTextBox = L3ControlFactory.CreateTextBox();
auditTimestampDateRange = new DateRangeControl();
sourceApplicationListBox = L3ControlFactory.CreateListBox();
operationNameTextBox = L3ControlFactory.CreateTextBox();
requestDataTextBox = L3ControlFactory.CreateTextBox();
responseDataTextBox = L3ControlFactory.CreateTextBox();
classNameTextBox = L3ControlFactory.CreateTextBox();
correlationIdTextBox = L3ControlFactory.CreateTextBox();
errorCodeTextBox = L3ControlFactory.CreateTextBox();
errorMessageTextBox = L3ControlFactory.CreateTextBox();

L3Form form = new L3Form();


Controls.Add(form);

L3Form leftForm = new L3Form();

leftForm.AddRow(mapper.GetLabelValue("correlationid"), correlationIdTextBox);
leftForm.AddRow(mapper.GetLabelValue("sourceapplication"), sourceApplicationListBox);
leftForm.AddRow(mapper.GetLabelValue("audittimestamp"), auditTimestampDateRange);

L3Form rightForm = new L3Form();

rightForm.AddRow(mapper.GetLabelValue("operationname"), operationNameTextBox);
rightForm.AddRow(mapper.GetLabelValue("requestdata"), requestDataTextBox);
rightForm.AddRow(mapper.GetLabelValue("responsedata"), responseDataTextBox);
rightForm.AddRow(mapper.GetLabelValue("classname"), classNameTextBox);
rightForm.AddRow(mapper.GetLabelValue("auditserviceid"), auditServiceIdTextBox);
rightForm.AddRow(mapper.GetLabelValue("errorcode"), errorCodeTextBox);
rightForm.AddRow(mapper.GetLabelValue("errormessage"), errorMessageTextBox);

form.AddRow(leftForm, rightForm);

if (Page.IsPostBack == false)
{
PopulateDropDowns();
}
}

#endregion

public override SearchCriteria Criteria


{
get
{
EnsureChildControls();

SearchCriteria criteria = new SearchCriteria();


94
criteria.Add("correlationid", SearchCriteriaValue.Create(correlationIdTextBox.Text));
criteria.Add("sourceapplication", SearchCriteriaValue.Create(sourceApplicationListBox.SelectedValue));
criteria.Add("audittimestamp", SearchCriteriaValue.CreateDateRange(auditTimestampDateRange.Range));
criteria.Add("operationname", SearchCriteriaValue.CreateLike(operationNameTextBox.Text, 100));
criteria.Add("requestdata", SearchCriteriaValue.CreateLike(requestDataTextBox.Text, 100));
criteria.Add("responsedata", SearchCriteriaValue.CreateLike(responseDataTextBox.Text, 100));
criteria.Add("classname", SearchCriteriaValue.CreateLike(classNameTextBox.Text, 100));
criteria.Add("auditserviceid", SearchCriteriaValue.Create(auditServiceIdTextBox.Text));
criteria.Add("errorcode", SearchCriteriaValue.Create(errorCodeTextBox.Text));
criteria.Add("errormessage", SearchCriteriaValue.CreateLike(errorMessageTextBox.Text, 100));

return criteria;
}
set
{
EnsureChildControls();

sourceApplicationListBox.SelectedValue = value.Get("sourceapplication").Value as string;


correlationIdTextBox.Text = value.Get("correlationid").Value as string;
auditTimestampDateRange.Range = value.Get("audittimestamp").Value as DateRange;
operationNameTextBox.Text = value.Get("operationname").Value as string;
requestDataTextBox.Text = value.Get("requestdata").Value as string;
responseDataTextBox.Text = value.Get("responsedata").Value as string;
classNameTextBox.Text = value.Get("classname").Value as string;
auditServiceIdTextBox.Text = value.Get("auditserviceid").Value as string;
errorCodeTextBox.Text = value.Get("errorcode").Value as string;
errorMessageTextBox.Text = value.Get("errormessage").Value as string;
}
}

private void PopulateDropDowns()


{
WebUtil.Populate(sourceApplicationListBox, mapper.GetGroup("sourceapplicationgroup"), true);
}

5. Add a new element to HWXmlMapper.xml at the same level as <Values> with:


<Groups>
<Group key="sourceapplicationgroup">
<GroupValue display="SLDB" value="SLDB" />
<GroupValue display="MOAB" value="MOAB" />
<GroupValue display="Soprano" value="SOPRANO" />
</Group>
</Groups>

6. The following elements inside the <Values> element of HWValueMapper.xml (note: the dtoValue
attribute is not used during this module but may be used in later modules):
<!-- DTO -->
<ValueItem key="auditserviceid" dtoValue="AuditServiceId" dbValue="AUDIT_SERVICE_ID"
presentationValue="Audit Service ID" />
<ValueItem key="audittimestamp" dtoValue="AuditTimestamp" dbValue="AUDIT_TIMESTAMP"
presentationValue="Audit Timestamp" />
<ValueItem key="sourceapplication" dtoValue="SourceApplication" dbValue="SOURCE_APPLICATION"
presentationValue="Source Application" />

95
<ValueItem key="operationName" dtoValue="OperationName" dbValue="OPERATION_NAME"
presentationValue="Operation Name" />
<ValueItem key="requestdata" dtoValue="RequestData" dbValue="REQUEST_DATA"
presentationValue="Request Data" />
<ValueItem key="responsedata" dtoValue="ResponseData" dbValue="RESPONSE_DATA"
presentationValue="Response Data" />
<ValueItem key="classname" dtoValue="ClassName" dbValue="CLASS_NAME" presentationValue="Class
Name" />
<ValueItem key="correlationid" dtoValue="CorrelationId" dbValue="CORRELATION_ID"
presentationValue="Correlation ID" />
<ValueItem key="errorcode" dtoValue="ErrorCode" dbValue="ERROR_CODE" presentationValue="Error Code"
/>
<ValueItem key="errormessage" dtoValue="ErrorMessage" dbValue="ERROR_MESSAGE"
presentationValue="Error Message" />

7. Create a new Cornerstone web page called “DataAccess1.aspx” in the HelloWorld web site and
add/change the code in the code-behind to:
using System;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;

public partial class DataAccess1 : HWPageBase


{
private SearchCriteriaControl criteriaControl;
private GridViewDefinition gridDefinition;
private SearchController searchController;

protected override void OnInit(EventArgs e)


{
base.OnInit(e);

EnsureChildControls();

ValidationManager.AddInfo("Database search example using grid view and the search control.");
}

protected override void CreateChildControls()


{
base.CreateChildControls();

criteriaControl = new UnifiedAuditingSearchCriteriaControl();


gridDefinition = HWGridViewFactory.Create("unifiedauditinggriddef");

searchController = new UnifiedAuditingSearchController();

SearchControl searchControl = new SearchControl(criteriaControl, searchController, gridDefinition);

Controls.Add(searchControl);
}
}

8. Save all files and browse the page DataAccess1.aspx.

96
Advanced Topics
• Live examples of Cornerstone code
• Advanced Unified Auditing Search Page
• Why we built the stubs.
• Personalization
• DTOs vs. Datasets
• Sitemap provider
• Page lifecycle in-depth
• Asynch Transactions
• Navigation and tabs
• Use of 3rd party assemblies
• Upload/download files
• AJAX in Cornerstone

Appendix: Coding Standards


Reference the Coding Standards document on the Cornerstone Sharepoint site

Appendix: ASP.NET Page Lifecycle

Appendix: Level 3 Environment Concerns


Source Control (setting up a VOB and view)
Include: 3rd_Party_DLL and Cornerstone
Build and Deployment (Panda and Nant)
Application Hosting
Multi-Environment Support (DEV1, DEV2, ENV1, ENV2…)
Solution file that is independent of the directory structure

97

Вам также может понравиться