Cornerstone Training

112
Cornerstone Application Framework Training Class 1 1

Transcript of Cornerstone Training

Page 1: Cornerstone Training

Cornerstone ApplicationFramework Training

Class 1

1

Page 2: Cornerstone Training

Table of ContentsCornerstone History.............................................................................................................................................3Class Setup...........................................................................................................................................................3Architecture Overview.........................................................................................................................................4Developing UIs with Cornerstone vs. Classic ASP.NET....................................................................................5Project Structure and Conventions......................................................................................................................5Developing the HelloWorld Solution..................................................................................................................6

Module 1: Creating the Application Solution..................................................................................................7Module 2: Integrating the ValueMapper.......................................................................................................14Module 3: Adding a Controller Project.........................................................................................................22Module 4: Form Layout and Handling Page Events.....................................................................................27Module 5: Consuming Web Services............................................................................................................37Module 6: Populating a GridView with Web Service Data..........................................................................55Module 7: HelloWorld Base Page and Using the Cornerstone SearchControl.............................................76Module 8: Consuming Data from a Database................................................................................................88

Advanced Topics...............................................................................................................................................97Appendix: Coding Standards.............................................................................................................................97Appendix: ASP.NET Page Lifecycle................................................................................................................97Appendix: Level 3 Environment Concerns.......................................................................................................97

2

Page 3: Cornerstone Training

Cornerstone HistoryThe 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 SetupThis 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 12. 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

Page 4: Cornerstone Training

Architecture OverviewThe 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

Page 5: Cornerstone Training

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.NETDeveloping 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 file3. 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

Page 6: Cornerstone Training

Developing the HelloWorld Solution

6

Page 7: Cornerstone Training

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

Page 8: Cornerstone Training

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 Studio3. Select FileNewWeb 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

Page 9: Cornerstone Training

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

Page 10: Cornerstone Training

{ 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

Page 11: Cornerstone Training

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

Page 12: Cornerstone Training

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 view10. 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

Page 13: Cornerstone Training

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

Page 14: Cornerstone Training

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

Page 15: Cornerstone Training

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

Page 16: Cornerstone Training

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

Page 17: Cornerstone Training

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

Page 18: Cornerstone Training

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

Page 19: Cornerstone Training

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

Page 20: Cornerstone Training

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.cs3. 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

Page 21: Cornerstone Training

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.GetPresentationValue("helloworld"))); }}

21

Page 22: Cornerstone Training

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

Page 23: Cornerstone Training

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

Page 24: Cornerstone Training

Source File Code 3.1: HelloWorldController.cs

namespace HelloWorld.Web.Controllers{ public class HelloWorldController { public string GenerateHelloWorldDisplayText() { return "Hello World! (from the controller)" } }}

24

Page 25: Cornerstone Training

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 file3. 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

Page 26: Cornerstone Training

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.GetPresentationValue("helloworld"))); Controls.Add(L3ControlFactory.CreateBreak()); Controls.Add(L3ControlFactory.CreateLabel(controller.GenerateHelloWorldDisplayText())); }}

26

Page 27: Cornerstone Training

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

Page 28: Cornerstone Training

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

Page 29: Cornerstone Training

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.GetPresentationValue("helloworld"))); Controls.Add(L3ControlFactory.CreateBreak()); Controls.Add(L3ControlFactory.CreateLabel(controller.GenerateHelloWorldDisplayText())); }}

29

Page 30: Cornerstone Training

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

Page 31: Cornerstone Training

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

Page 32: Cornerstone Training

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

Page 33: Cornerstone Training

getValuesButton.Click += getValuesButton_Click;

Button clearValuesButton = L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("clearvalues")); 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

Page 34: Cornerstone Training

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

Page 35: Cornerstone Training

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("clearvalues")); 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

Page 36: Cornerstone Training

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

Page 37: Cornerstone Training

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

Page 38: Cornerstone Training

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.cs3. 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

Page 39: Cornerstone Training

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.cs3. 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

Page 40: Cornerstone Training

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

Page 41: Cornerstone Training

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

Page 42: Cornerstone Training

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

Page 43: Cornerstone Training

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

Page 44: Cornerstone Training

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

Page 45: Cornerstone Training

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

Page 46: Cornerstone Training

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

Page 47: Cornerstone Training

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

Page 48: Cornerstone Training

//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

Page 49: Cornerstone Training

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

Page 50: Cornerstone Training

{ LocStateVO retVO = new LocStateVO(); retVO.sequenceLock = -1; return retVO; } } #endregion }}

50

Page 51: Cornerstone Training

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 L3PageTemplate5. 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

Page 52: Cornerstone Training

10. Save all files and browse the WebServices1.aspx

52

Page 53: Cornerstone Training

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

Page 54: Cornerstone Training

{ 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

Page 55: Cornerstone Training

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

Page 56: Cornerstone Training

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

Page 57: Cornerstone Training

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

Page 58: Cornerstone Training

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

Page 59: Cornerstone Training

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

Page 60: Cornerstone Training

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

Page 61: Cornerstone Training

{ 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

Page 62: Cornerstone Training

//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

Page 63: Cornerstone Training

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.cs3. 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

Page 64: Cornerstone Training

</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

Page 65: Cornerstone Training

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

Page 66: Cornerstone Training

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

Page 67: Cornerstone Training

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

Page 68: Cornerstone Training

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

Page 69: Cornerstone Training

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

Page 70: Cornerstone Training

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

Page 71: Cornerstone Training

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);toresultsGrid = 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

Page 72: Cornerstone Training

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

Page 73: Cornerstone Training

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

Page 74: Cornerstone Training

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

Page 75: Cornerstone Training

#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.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)); }

protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); }

#endregion}

75

Page 76: Cornerstone Training

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

Page 77: Cornerstone Training

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

Page 78: Cornerstone Training

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

Page 79: Cornerstone Training

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 SearchCriteriaControl7. 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

Page 80: Cornerstone Training

{ 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

Page 81: Cornerstone Training

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; lataTextBox.Text = (string)value["lata"].Value;

81

Page 82: Cornerstone Training

} }

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

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

82

Page 83: Cornerstone Training

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

Page 84: Cornerstone Training

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

Page 85: Cornerstone Training

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

Page 86: Cornerstone Training

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

Page 87: Cornerstone Training

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

Page 88: Cornerstone Training

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

Page 89: Cornerstone Training

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

Page 90: Cornerstone Training

10. Save and build the HelloWorld.Services project.

90

Page 91: Cornerstone Training

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

Page 92: Cornerstone Training

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

Page 93: Cornerstone Training

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_CodeWebControlsCriteriaControls 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

Page 94: Cornerstone Training

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

Page 95: Cornerstone Training

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

Page 96: Cornerstone Training

<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

Page 97: Cornerstone Training

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 StandardsReference the Coding Standards document on the Cornerstone Sharepoint site

Appendix: ASP.NET Page Lifecycle

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

97