Cornerstone Training

  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Cornerstone Training as PDF for free.

More details

  • Words: 9,897
  • Pages: 97
Cornerstone Application Framework Training Class 1

1

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

2

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

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

3

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

The Cornerstone reference design dismisses use of the .ASPX page and relies entirely on the codebehind (aspx.cs) and related embedded controls as the presentation tier. This allows for a more consistent control tree and simplifies debugging. Many of the Cornerstone controls are instantiated by using L3ControlFactory, which adheres to the factory pattern and provides consistency. The controller tier acts as a conduit between the presentation tier and the data access tier. It processes and responds to events and routes data accordingly. The flow controller, which guides page flow and manages state and transfer parameters, also resides here. 4

The data access tier encapsulates all web service calls and database interaction. A ServiceFactory is used to instantiate these object based on UDDI endpoints or provides application independence by seamlessly allowing for stubs (mock data) to be used in their place. Enabling or disabling service stubs is simple process involving a web.config change, and can be performed at runtime.

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

Project Structure and Conventions • •

• •

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

5

Developing the HelloWorld Solution

6

Module 1: Creating the Application Solution Module Goal:

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

7

Procedure 1.1: Creating the HelloWorld web site

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

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

8

Procedure 1.2: Adding a HelloWorld page

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

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

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

9

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

11. Save all files and browse the page.

10

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

Source File Code 1.2: HelloWorldPage.aspx.cs using System; using Level3.Cornerstone.Web.WebControls; public partial class HelloWorldPage : L3PageTemplate { protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); } protected override void CreateChildControls() { base.CreateChildControls(); Controls.Add((L3ControlFactory.CreateLabel("Hello World"))); } }

11

Procedure 1.3: Adding a Header, Footer, and Style Sheet

1. Create a folder in the web site called "Styles" 2. Add the file HelloWorldStyle.css to the Styles folder from the location your instructor gives you. 3. Open Web.config and add the following under the line ""

4. Right click the HelloWorld web site and select "New Folder" 5. Rename the new folder "UserControls". This is where the header and footer for the application pages will be kept. 6. Right click the "UserControls" folder and select "Add New Item…" 7. Add a "Web User Control" called "Header.ascx" 8. Repeat the previous two steps to add "Footer.ascx" 9. Add the following to Header.ascx source view 10. Open the source view for Header.ascx and add the following to the end of the file:
HelloWorld Header


11. Open the source view for Footer.ascx and add the following to the end of the file:
HelloWorld Footer


12. Save all files and browse the page.

12

Source File Code 1.3: Header.ascx <%@ Control Language="C#" AutoEventWireup="true" CodeFile="Header.ascx.cs" Inherits="UserControls_Header" %>
HelloWorld Header


Source File Code 1.3: Footer.ascx <%@ Control Language="C#" AutoEventWireup="true" CodeFile="Footer.ascx.cs" Inherits="UserControls_Footer" %>
HelloWorld Footer


13

Module 2: Integrating the ValueMapper Module Goal:

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

14

Procedure 2.1: Creating the HelloWorld.Common project and adding the ValueMapper

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

4. Add a reference to the Level3.Cornerstone.Common.dll and Level3.Cornerstone.Web.dll assemblies from the path your instructor gives you. 5. Add a new Class to the HelloWorld.Common project called HWValueMapper.cs.

6. Remove all of the using statements in the HWValueMapper.cs class file. Add the following using statements to the class: 15

using System.IO; using System.Web; using Level3.Cornerstone.Common.ValueMapper;

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

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

16

Source File Code 2.1: HWValueMapper.cs using System.IO; using System.Web; using Level3.Cornerstone.Common.ValueMapper; namespace HelloWorld.Common { /// <summary> /// Singleton Wrapper on <see cref="IValueMapper"/> /// public class HWValueMapper { private static IValueMapper instance; private HWValueMapper() { } public static IValueMapper Instance { get { if (instance == null) { string ResourceFile = "App_LocalResources\\HWValueMapper.xml"; FileStream stream = new FileStream(HttpContext.Current.Server.MapPath(ResourceFile), FileMode.Open, FileAccess.Read); instance = ValueMapperFactory.Create(new Stream[] { stream }); } return instance; } }

}

}

17

Procedure 2.2: Creating the ValueMapper resource file

1. Right-click the HelloWorld_Solution web site, and select "App_LocalResources" the "Add ASP.NET Folder" menu. 2. Right click the "App_LocalResources folder and add an XML file called HWValueMapper.xml. 3. Add the following line to the bottom of HWValueMapper.xml: <Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">

18

Source File Code 2.2: HWValueMapper.xml <Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">

19

Procedure 2.3: Using the ValueMapper in HelloWorldPage

1. 2. 3. 4.

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

5. Save all files and browse the page.

20

Source File Code 2.3: HelloWorldPage.aspx.cs using System; using HelloWorld.Common; using Level3.Cornerstone.Web.WebControls; public partial class HelloWorldPage : L3PageTemplate { protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); } protected override void CreateChildControls() { base.CreateChildControls(); Controls.Add((L3ControlFactory.CreateLabel("Hello World"))); Controls.Add(L3ControlFactory.CreateBreak()); Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentat ionValue("helloworld"))); } }

21

Module 3: Adding a Controller Project Module Goal:

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

22

Procedure 3.1: Creating the HelloWorld.Web.Controllers project and adding a controller

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

23

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

24

Procedure 3.2: Using the HelloWorld Controller

1. 2. 3. 4.

Add a reference to the HelloWorld.Web.Controllers project to the HelloWorld web site. Open the HelloWorldPage.aspx.cs file Add the using statement "using HelloWorld.Web.Controllers;" Add a member variable to the class called "controller" with the statement: HelloWorldController controller = new HelloWorldController();

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

25

Source File Code 3.2: HelloWorldPage.aspx.cs using using using using

System; HelloWorld.Common; Level3.Cornerstone.Web.WebControls; HelloWorld.Web.Controllers;

public partial class HelloWorldPage : L3PageTemplate { HelloWorldController controller = new HelloWorldController(); protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); } protected override void CreateChildControls() { base.CreateChildControls(); Controls.Add((L3ControlFactory.CreateLabel("Hello World"))); Controls.Add(L3ControlFactory.CreateBreak()); Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentat ionValue("helloworld"))); Controls.Add(L3ControlFactory.CreateBreak()); Controls.Add(L3ControlFactory.CreateLabel(controller.GenerateHelloWorldDispla yText())); } }

26

Module 4: Form Layout and Handling Page Events Module Goal:

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

27

Procedure 4.1: Adding the L3Form and L3Border controls

1. In CreateChildControls() for HelloWorldPage.aspx.cs, add the line L3Form form = new L3Form();

immediately below base.CreateChildControls();

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

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

4. Save and browse the page.

28

Source File Code 4.1: HelloWorldPage.aspx.cs using using using using

System; HelloWorld.Common; Level3.Cornerstone.Web.WebControls; HelloWorld.Web.Controllers;

public partial class HelloWorldPage : L3PageTemplate { HelloWorldController controller = new HelloWorldController(); protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); } protected override void CreateChildControls() { base.CreateChildControls(); L3Form form = new L3Form(); form.AddRow("Static:",L3ControlFactory.CreateLabel("Hello World!")); form.AddRow("From ValueMapper:", L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentationValue("helloworld" ))); form.AddRow("From Controller:", controller.GenerateHelloWorldDisplayText()); Controls.Add(L3Border.WrapControl(form, "This is the L3Border control")); Controls.Add((L3ControlFactory.CreateLabel("Hello World"))); Controls.Add(L3ControlFactory.CreateBreak()); Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentat ionValue("helloworld"))); Controls.Add(L3ControlFactory.CreateBreak()); Controls.Add(L3ControlFactory.CreateLabel(controller.GenerateHelloWorldDispla yText())); } }

29

Procedure 4.2: Adding the L3ButtonPanel and Event Handlers

1. Add the following items to the HWValueMapper.xml:

2. Open HelloWorldPage.aspx.cs and add using statements for System.Web.UI.WebControls and Level3.Cornerstone.Web.Images. 3. Add two private member variables of type Label to the HelloWorldPage class called helloWorldFromValueMapper and helloWorldFromController private Label helloWorldFromValueMapper = new Label(); private Label helloWorldFromController = new Label();

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

6. Add an L3ButtonPanel with the statement: L3ButtonPanel buttonPanel = new L3ButtonPanel();

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

8. Add the buttons to the L3ButtonPanel with the following statements: buttonPanel.AddRightControl(getValuesButton); buttonPanel.AddRightControl(clearValuesButton);

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

10. Add the delegate methods for the buttons' click events with the following: #region Button Events private void getValuesButton_Click(object sender, EventArgs e) { helloWorldFromValueMapper.Text = HWValueMapper.Instance.GetPresentationValue("helloworld");

30

helloWorldFromController.Text = controller.GenerateHelloWorldDisplayText(); } private void clearValuesButton_Click(object sender, EventArgs e) { InitializeValues(); } #endregion

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

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

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

31

Source File Code 4.2: HWValueMapper.xml <Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">

Source File Code 4.2: HelloWorldPage.aspx.cs using using using using using using

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

public partial class HelloWorldPage : L3PageTemplate { HelloWorldController controller = new HelloWorldController(); private Label helloWorldFromController = new Label(); private Label helloWorldFromValueMapper = new Label(); protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); if (!Page.IsPostBack) { InitializeValues(); } } protected override void CreateChildControls() { base.CreateChildControls(); L3Form form = new L3Form(); form.AddRow("From ValueMapper:", helloWorldFromValueMapper); form.AddRow("From Controller:", helloWorldFromController); L3ButtonPanel buttonPanel = new L3ButtonPanel(); Button getValuesButton = L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("getvalues" ));

32

getValuesButton.Click += getValuesButton_Click; Button clearValuesButton = L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("clearvalue s")); clearValuesButton.Click += clearValuesButton_Click; buttonPanel.AddRightControl(getValuesButton); buttonPanel.AddRightControl(clearValuesButton); L3Border border = L3Border.WrapControl(form, " Hello World L3 Border", L3Icon.World, buttonPanel); Controls.Add(border); }

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

#region Button Events private void getValuesButton_Click(object sender, EventArgs e) { helloWorldFromValueMapper.Text = HWValueMapper.Instance.GetPresentationValue("helloworld"); helloWorldFromController.Text = controller.GenerateHelloWorldDisplayText(); } private void clearValuesButton_Click(object sender, EventArgs e) { InitializeValues(); } #endregion private void InitializeValues() { helloWorldFromValueMapper.Text = "Click 'Get Values' to retrieve this."; helloWorldFromController.Text = "Click 'Get Values' to retrieve this."; } }

33

Procedure 4.3: Adding the Validation Manager

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

3. In getValuesButton_Click add the following statement: ValidationManager.AddSuccess("'Get Values' clicked.");

4. In clearValuesButton_Click add the following statement: ValidationManager.AddSuccess("'Clear Values' clicked.");

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

34

Source File Code: HelloWorldPage.aspx.cs using using using using using using using

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

public partial class HelloWorldPage : L3PageTemplate { HelloWorldController controller = new HelloWorldController(); private Label helloWorldFromController = new Label(); private Label helloWorldFromValueMapper = new Label(); protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e);

}

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

protected override void CreateChildControls() { base.CreateChildControls(); L3Form form = new L3Form(); form.AddRow("From ValueMapper:", helloWorldFromValueMapper); form.AddRow("From Controller:", helloWorldFromController); L3ButtonPanel buttonPanel = new L3ButtonPanel(); Button getValuesButton = L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("getvalues" )); getValuesButton.Click += getValuesButton_Click; Button clearValuesButton = L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("clearvalue s")); clearValuesButton.Click += clearValuesButton_Click; buttonPanel.AddRightControl(getValuesButton); buttonPanel.AddRightControl(clearValuesButton); L3Border border = L3Border.WrapControl(form, " Hello World L3 Border", L3Icon.World, buttonPanel); Controls.Add(border); Controls.Add(L3Border.WrapControl(form, "This is the L3Border control"));

35

ValidationManager.AddInfo("This is an example of event handling and the page lifecycle."); } #region Button Events private void getValuesButton_Click(object sender, EventArgs e) { helloWorldFromValueMapper.Text = HWValueMapper.Instance.GetPresentationValue("helloworld"); helloWorldFromController.Text = controller.GenerateHelloWorldDisplayText(); ValidationManager.AddSuccess("'Get Values' clicked."); } private void clearValuesButton_Click(object sender, EventArgs e) { InitializeValues(); }

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

#endregion private void InitializeValues() { helloWorldFromValueMapper.Text = "Click 'Get Values' to retrieve this."; helloWorldFromController.Text = "Click 'Get Values' to retrieve this."; } }

36

Module 5: Consuming Web Services Module Goal:

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

37

Procedure 5.1: Creating the HelloWorld.Services project and web reference

1. Create a new class library project in c:\HelloWorld_Solution called HelloWorld.Services. 2. Delete the file Class1.cs 3. Add references to Level3.Cornerstone.UDDIRegistry.dll and Level3.Cornerstone.Common from the distribution folder. 4. Add the following to web.config under the node : <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"/>

5. Add the following to web.config above the node
. These values are used later to point at the different environments where the web services are published: <services> <ServiceProperties> <ServiceItem name="TaiWebService" mockOn="false"/>

6. Add a web reference to the HelloWorld.Services project with URL = http://taienv3ws.l3.com/tai/maint/ws?wsdl and Web Reference Name = WebServices.TAI.Maint

38

Procedure 5.2: Creating an Interface for the TAI web service

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

39

Source File Code 5.2: ITaiWebService.cs using HelloWorld.Services.WebServices.TAI.Maint; namespace HelloWorld.Services.WebServices { public interface ITaiWebService { LocStateVO[] FindAllLocState(LocStateVO locStateVO); } }

40

Procedure 5.3: Creating an implementaion of the ITaiWebService interface

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

4. Inherit the ITaiWebService interface: class TaiWebService : ITaiWebService

5. Add two private member variables: private string serviceName = typeof(TAI_WebServices).Name; private SoapHttpClientProtocol service;

6. Add a public constructor to the class with the following: public TaiWebService() { service = new TAI_WebServices(); IRegistry registry = RegistryManager.Load(); registry.Bind(serviceName, service); }

7. Implement the method FindAllLocState from the interface with: public LocStateVO[] FindAllLocState(LocStateVO locStateVo) { return Array.ConvertAll((service as TAI_WebServices).findAllLocState(locStateVo), new Converter(LocStateObjectConverter)); }

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

41

Source File Code 5.3: TaiWebService.cs using using using using

System; System.Web.Services.Protocols; HelloWorld.Services.WebServices.TAI.Maint; 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(LocStateObjectConverter)); } #endregion #region Converters public static LocStateVO LocStateObjectConverter(object obj) { return (LocStateVO)obj; } }

#endregion

42

Procedure 5.4: Creating a stub for TAI web service

1. Add a folder in the HelloWorld.Services project called "Stubs" 2. Add a class file in the "Stubs" folder called TaiWebServiceStub.cs. 3. Add the using statements: using HelloWorld.Services.WebServices; using HelloWorld.Services.WebServices.TAI.Maint;

4. Make the class public and inherit the ITaiWebService interface. 5. Add the following methods to the class: public LocStateVO[] FindAllLocState(LocStateVO locStateVo) { int numStates = 50; LocStateVO[] locStates = new LocStateVO[numStates]; for (int i = 0; i < numStates; i++) { locStates[i] = BuildLocStateVO(i); } return locStates; } LocStateVO BuildLocStateVO(int id) { LocStateVO locStateVo = new LocStateVO(); locStateVo.name = "Name-" + id; locStateVo.abbrev = "Abbrev-" + id; locStateVo.lastUpdateDate = DateTime.Now.ToString(); locStateVo.lastUpdateUser = "User-" + id; return locStateVo; }

43

Source File Code 5.4: TaiWebServiceStub.cs using System; using HelloWorld.Services.WebServices; using HelloWorld.Services.WebServices.TAI.Maint; namespace HelloWorld.Services.Stubs { public class TaiWebServiceStub : ITaiWebService { #region ITaiWebService Members public LocStateVO[] FindAllLocState(LocStateVO locStateVo) { int numStates = 50; LocStateVO[] locStates = new LocStateVO[numStates]; for (int i = 0; i < numStates; i++) { locStates[i] = BuildLocStateVO(i); } return locStates; } #endregion #region Helpers LocStateVO BuildLocStateVO(int id) { LocStateVO locStateVo = new LocStateVO(); locStateVo.name = "Name-" + id; locStateVo.abbrev = "Abbrev-" + id; locStateVo.lastUpdateDate = DateTime.Now.ToString(); locStateVo.lastUpdateUser = "User-" + id; }

return locStateVo;

#endregion }

}

44

Procedure 5.5: Creating the ServiceFactory

The ServiceFactory instantiates services based on UDDI endpoints and seamlessly allows for stubs. An element must be added to the serviceDictionary for each service type to be supported. The serviceDictionary is keyed off of the interface type name and uses the service name to look up the mockOn value for that service in the web.config ServiceProperties section. Based on this flag the service factory instantiates one of two possibilities: the actual service or a stubbed implementation. In this way, live and mock data can be toggled at runtime without a code change. A ServiceFactory subclass, named appropriately for your application, must exist within your solution in order to have the proper scope necessary to access local service objects. 1. Add a new class file to HelloWorld.Services called HWServiceFactory. 2. Replace the code in this class file with the following: using System; using System.Collections.Generic; using System.Text; using HelloWorld.Services.Stubs; using HelloWorld.Services.WebServices; using Level3.Cornerstone.Common.ServiceFactory; namespace HelloWorld.Services { public enum ServiceTypes { TaiWebService } /// <summary> /// Factory for creating services /// /// <exception>ServicesFactoryException if unable to create the type specified. public sealed class CSTServicesFactory { private static readonly IServiceFactory serviceFactory = new CSTServiceFactory(); private CSTServicesFactory() { } public static TService Create() where TService : class { return (TService)ServicesFactory.Create(serviceFactory, typeof(TService)); } /// <summary> /// Creates the correct ServiceFactory based on the type. /// public class CSTServiceFactory : IServiceFactory { Dictionary serviceDictionary = new Dictionary(); internal CSTServiceFactory() { // Include code here to handle every service type. serviceDictionary.Add(typeof(ITaiWebService), new ServiceFactory(ServiceTypes.TaiWebService.ToString(), typeof(TaiWebService), typeof(TaiWebServiceStub))); }

45

public ServiceFactory Create(object serviceType) { Type t = (Type)serviceType; if (!serviceDictionary.ContainsKey(t)) { throw new Exception(BuildErrorMessage(t.Name)); } return serviceDictionary[t]; } private string BuildErrorMessage(string serviceName) { StringBuilder msg = new StringBuilder(); msg.Append(string.Format("Service '{0}' is not defined in Service Factory/", serviceName)); msg.Append(Environment.NewLine); msg.Append("Available Services Include:"); msg.Append(Environment.NewLine); foreach (Type type in serviceDictionary.Keys) { msg.Append(type.Name); msg.Append(Environment.NewLine); } return msg.ToString(); } } } }

3. Save all files and build the HelloWorld.Services project.

46

Procedure 5.6: Creating a controller for the WebService

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

5. Add a private member to the class with: private ITaiWebService webService;

6. Add two class constructors for the class with: public WebServiceController() : this(CSTServicesFactory.Create()) { } public WebServiceController(ITaiWebService webService) { this.webService = webService; }

7. Add the following public method (GetStates) and property (EmptyLocStateVO) to the class: public SortedList GetStates() { try { LocStateVO[] locStates = webService.FindAllLocState(BuildEmptyLocStateVO); SortedList stateList = new SortedList(); foreach (LocStateVO locState in locStates) { stateList.Add(locState.abbrev,locState.name); } return stateList; } catch (Exception ex) { ValidationManager.AddFailure("GetStateNameAbbreviations failed: " + ex.Message); return new SortedList(); } } public static LocStateVO EmptyLocStateVO { //The web service expects a null for "unset" integers, but .NET //doesn't allow this. Compromise: Set INT fields equal to -1

47

//the service will read these as null get { LocStateVO retVO = new LocStateVO(); retVO.sequenceLock = -1; return retVO; } }

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

48

Source File Code 5.6: WebServiceController.cs using using using using using using

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

namespace HelloWorld.Web.Controllers { public class WebServiceController { private ITaiWebService webService; #region Constructors public WebServiceController() : this(CSTServicesFactory.Create()) { } public WebServiceController(ITaiWebService webService) { this.webService = webService; } #endregion #region Members public SortedList GetStates() { try { LocStateVO[] locStates = webService.FindAllLocState(EmptyLocStateVO()); SortedList stateList = new SortedList(); foreach (LocStateVO locState in locStates) { stateList.Add(locState.abbrev,locState.name); } return stateList; } catch (Exception ex) { ValidationManager.AddFailure("GetStateNameAbbreviations failed: " + ex.Message); }

return new SortedList(); }

public static LocStateVO EmptyLocStateVO { //The web service expects a null for "unset" integers, but .NET //doesn't allow this. Compromise: Set INT fields equal to -1 //the service will read these as null get

49

{

}

LocStateVO retVO = new LocStateVO(); retVO.sequenceLock = -1; return retVO;

} } #endregion

}

50

Procedure 5.7: Populating a drop down list with data from the TAI web service

1. Add a new Cornerstone web page from the template to the HelloWorld web site called WebService1.aspx. 2. Add a ValueItem to HWValueMapper.xml with:

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

4. Change the inheritance from System.Web.UI.Page to L3PageTemplate 5. Add two private members to the class: private WebServiceController controller; private DropDownList stateList;

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

7. Add the private method PopulateDropDowns: private void PopulateDropDowns() { SortedList states = controller.GetStates(); if (states != null && states.Count > 0) { ValidationManager.AddSuccess(states.Count + " values returned from web service."); stateList.DataSource = states; stateList.DataTextField = "value"; stateList.DataValueField = "key"; stateList.DataBind(); } }

8. Add a call to PopulateDropDowns in the "if(!IsPostBack) of the OnPreRender event. 9. In CreateChildControls add the following after the call to base.CreateChildControls(): stateList = L3ControlFactory.CreateDropDown(); L3Form form = new L3Form(); form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList); ValidationManager.AddInfo("This is an example of using a remote web service to populate a dropdown list."); Controls.Add(L3Border.WrapControl(form, "Web Service Example 1", L3Icon.Application));

51

10. Save all files and browse the WebServices1.aspx

52

Source File Code 5.7: WebService1.aspx.cs using using using using using using using using

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

public partial class WebService1 : L3PageTemplate { #region Attributes private WebServiceController controller; private DropDownList stateList; #endregion #region Control Overrides protected override void OnInit(EventArgs e) { controller = new WebServiceController(); base.OnInit(e); EnsureChildControls(); } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); if (!IsPostBack) { PopulateDropDowns(); } } protected override void CreateChildControls() { base.CreateChildControls(); stateList = L3ControlFactory.CreateDropDown(); L3Form form = new L3Form(); form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList); ValidationManager.AddInfo("This is an example of using a remote web service to populate a dropdown list."); Controls.Add(L3Border.WrapControl(form, "Web Service Example 1", L3Icon.Application)); } #endregion #region Private Methods private void PopulateDropDowns()

53

{

SortedList states = controller.GetStates();

if (states != null && states.Count > 0) { ValidationManager.AddSuccess(states.Count + " values returned from web service."); stateList.DataSource = states; stateList.DataTextField = "value"; stateList.DataValueField = "key"; stateList.DataBind();

}

} } #endregion

54

Module 6: Populating a GridView with Web Service Data Module Goal:

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

55

Procedure 6.1: Updating the TAI Service code with new methods

1. Open ITaiWebService.cs and add a method signature for FindAllRateCenter and FindOneRateCenter with: RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVO); RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo);

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

3. Implement FindAllRateCenter and FindOneRateCenter in TaiWebService.cs with the method: public RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVo) { return Array.ConvertAll((service as TAI_WebServices).findAllRateCenter(rateCenterVo), new Converter(RateCenterObjectConverter)); } public RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo) { return (service as TAI_WebServices).findOneRateCenter(rateCenterVo); }

4. Open TaiWebServiceStub and add a method to it for FindAllRateCenter, FindOneRateCenter, and BuildRateCenterVO similar to what we did with LocStateVOs with: public RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVo) { int numRcs = 50; RateCenterVO[] rcs = new RateCenterVO[numRcs]; for (int i = 0; i < numRcs; i++) { rcs[i] = BuildRateCenterVO(i); } return rcs; } public RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo) { return BuildRateCenterVO(1); } RateCenterVO BuildRateCenterVO(int id) { RateCenterVO rateCenterVo = new RateCenterVO(); rateCenterVo.rcAbbrev = "rcAbbrev-" + id; rateCenterVo.stateAbbrev = "stateAbbrev-" + id; rateCenterVo.rateCenterEid = id;

56

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

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

6. Add the public methods GetRateCentersForStateAbbreviation and GetRateCentersByEid to WebServiceController.cs: public RateCenterVO[] GetRateCentersForStateAbbreviation(string stateAbbrev) { RateCenterVO rateCenter = EmptyRateCenterVO; rateCenter.stateAbbrev = stateAbbrev; RateCenterVO[] rateCenterResults = webService.FindAllRateCenter(rateCenter); return rateCenterResults; } public RateCenterVO GetRateCentersByEid(int eid) { RateCenterVO rateCenter = EmptyRateCenterVO; rateCenter.rateCenterEid = eid; RateCenterVO rateCenterResult = webService.FindOneRateCenter(rateCenter); return rateCenterResult; }

7. Save all files and build the solution.

57

Source File Code 6.1: ITaiWebServices.cs using HelloWorld.Services.WebServices.TAI.Maint; namespace HelloWorld.Services.WebServices { public interface ITaiWebService { LocStateVO[] FindAllLocState(LocStateVO locStateVO); RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVO); RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo); } }

Source File Code 6.1: TaiWebServices.cs using using using using

System; System.Web.Services.Protocols; HelloWorld.Services.WebServices.TAI.Maint; 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(LocStateObjectConverter)); } public RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVo) { return Array.ConvertAll((service as TAI_WebServices).findAllRateCenter(rateCenterVo), new Converter(RateCenterObjectConverter)); } public RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo) { return (service as TAI_WebServices).findOneRateCenter(rateCenterVo); } #endregion #region Converters

58

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

#endregion

}

Source File Code 6.1: TaiWebServicesStub.cs using System; using HelloWorld.Services.WebServices; using HelloWorld.Services.WebServices.TAI.Maint; namespace HelloWorld.Services.Stubs { public class TaiWebServiceStub : ITaiWebService { #region ITaiWebService Members public LocStateVO[] FindAllLocState(LocStateVO locStateVo) { int numStates = 50; LocStateVO[] locStates = new LocStateVO[numStates]; for (int i = 0; i < numStates; i++) { locStates[i] = BuildLocStateVO(i); } return locStates; } public RateCenterVO[] FindAllRateCenter(RateCenterVO rateCenterVo) { int numRcs = 50; RateCenterVO[] rcs = new RateCenterVO[numRcs]; for (int i = 0; i < numRcs; i++) { rcs[i] = BuildRateCenterVO(i); } return rcs; } public RateCenterVO FindOneRateCenter(RateCenterVO rateCenterVo) { return BuildRateCenterVO(1); } #endregion #region Helpers LocStateVO BuildLocStateVO(int id) {

59

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

return locStateVo;

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

#endregion

}

Source File Code 6.1: WebServiceController.cs using using using using using using

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

namespace HelloWorld.Web.Controllers { public class WebServiceController { private ITaiWebService webService; #region Constructors public WebServiceController() : this(CSTServicesFactory.Create()) { } public WebServiceController(ITaiWebService webService) { this.webService = webService; } #endregion #region Members public SortedList GetStates() { try

60

{

LocStateVO[] locStates = webService.FindAllLocState(EmptyLocStateVO); SortedList stateList = new SortedList(); foreach (LocStateVO locState in locStates) { stateList.Add(locState.abbrev,locState.name); }

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

return new SortedList(); }

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

return rateCenterResults;

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

61

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

return retVO;

} }

#endregion

}

62

Procedure 6.2: Creating the GridViewFactory and a GridView definition

1. Add a reference to Cornerstone.Web.dll in the HelloWorld.Common project. 2. Create a new class file in the HelloWorld.Common project called HWGridViewFactory.cs 3. Replace all the code in the HWGridViewFactory.cs with the following: using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Text; using System.Web; using Level3.Cornerstone.Web.WebControls; namespace HelloWorld.Common { /// <summary> /// Creates data grid defs from the xml file GridDefinitions.xml /// 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:

63



6. Add the following values to HWValueMapper.xml under the Values element:

64

Source File Code 6.2: HWGridViewFactory.cs using System.IO; using System.Web; using Level3.Cornerstone.Web.WebControls; namespace HelloWorld.Common { /// <summary> /// Creates data grid defs from the xml file GridDefinitions.xml /// 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

65

Procedure 6.3: Creating the Rate Center search page

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

3. Add the following member variables: private bool autoCollapseCriteria = true; private WebServiceController controller; private DropDownList stateList; private Button submitButton; private L3GridView resultsGrid; private L3Border criteriaBorder; private L3Border resultsBorder;

4. In OnInit before the base.OnInit is called: controller = new WebServiceController();

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

6. In CreateChildControls add the following after base.CreateChildControls is called: stateList = L3ControlFactory.CreateDropDown(); L3Form form = new L3Form(); form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList); L3ButtonPanel bp = new L3ButtonPanel(); submitButton = L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("submit")); submitButton.Click += new EventHandler(submitButton_Click); bp.AddRightControl(submitButton); criteriaBorder = L3Border.WrapControl(form, "Web Service Example 2", L3Icon.Application, bp); GridViewDefinition rateCenterGridView = HWGridViewFactory.Create("ratecentergriddef"); resultsGrid = L3GridView.Create(rateCenterGridView, true); resultsBorder = L3Border.WrapControl(resultsGrid, "Rate Center Results"); ValidationManager.AddInfo("This is an example of a basic search using a remote web service.");

66

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

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

8. In the "Private Methods" region add the following two methods: private void PopulateResultsGrid(RateCenterVO[] rateCenters) { if (rateCenters.Length == 0) { resultsBorder.Visible = false; } else { resultsBorder.Visible = true; resultsGrid.Populate(rateCenters); if (autoCollapseCriteria) { criteriaBorder.Collapsed = true; } } } private void PopulateDropDowns() { SortedList states = controller.GetStates (); if (states != null && states.Count > 0) { stateList.DataSource = states; stateList.DataTextField = "value"; stateList.DataValueField = "key"; stateList.DataBind(); } }

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

67

Source File Code 6.3: WebService2.xml using using using using using using using using using

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

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

WebServiceController controller; DropDownList stateList; Button submitButton; L3GridView resultsGrid; L3Border criteriaBorder; L3Border resultsBorder;

#endregion #region Control Overrides protected override void OnInit(EventArgs e) { controller = new WebServiceController();

}

base.OnInit(e); EnsureChildControls();

protected override void CreateChildControls() { base.CreateChildControls(); stateList = L3ControlFactory.CreateDropDown(); L3Form form = new L3Form(); form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList); L3ButtonPanel bp = new L3ButtonPanel(); submitButton = L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("submit")); submitButton.Click += new EventHandler(submitButton_Click); bp.AddRightControl(submitButton); criteriaBorder = L3Border.WrapControl(form, "Web Service Example 2", L3Icon.Application, bp); GridViewDefinition rateCenterGridView = HWGridViewFactory.Create("ratecentergriddef");

68

resultsGrid = L3GridView.Create(rateCenterGridView, true); resultsBorder = L3Border.WrapControl(resultsGrid, "Rate Center Results"); ValidationManager.AddInfo("This is an example of a basic search using a remote web service."); Controls.Add(criteriaBorder); Controls.Add(resultsBorder); } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); if (!IsPostBack) { PopulateDropDowns(); resultsBorder.Visible = false; } } #endregion #region Events void submitButton_Click(object sender, EventArgs e) { try { RateCenterVO[] rateCenters = controller.GetRateCentersForStateAbbreviation(stateList.SelectedValue); PopulateResultsGrid(rateCenters); } catch (Exception ex) { ValidationManager.AddFailure("An error occurred getting rate centers: " + ex.Message); } } #endregion #region Private Methods private void PopulateResultsGrid(RateCenterVO[] rateCenters) { if (rateCenters.Length == 0) { resultsBorder.Visible = false; } else { resultsBorder.Visible = true; resultsGrid.Populate(rateCenters); if (autoCollapseCriteria) { criteriaBorder.Collapsed = true; } }

}

69

private void PopulateDropDowns() { SortedList states = controller.GetStates(); if (states != null && states.Count > 0) { stateList.DataSource = states; stateList.DataTextField = "value"; stateList.DataValueField = "key"; stateList.DataBind(); } } }

#endregion

70

Procedure 6.4: Adding export and paging to the rate center grid

1. Open WebService2.aspx.cs. 2. In the CreateChildControls the line resultsGrid = L3GridView.Create(rateCenterGridView, true); to resultsGrid = L3GridView.Create(rateCenterGridView, true, 10);

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

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

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

71

Procedure 6.5: Creating the Rate Center detail page

1. Open HWGridDefinitions.xml and add the following element to the definition of the "ratecentergriddef" which adds an action icon to the GridView and defines which page the request will be routed to when the user clicks the action icon: <Parameter dataFieldKey="rateCenterEid" id="ratecentereid"/>

2. If not already there, add the property "checkBoxDataFieldKey="rateCenterEid" to "ratecentergriddef" 3. Add the following item to HWValueMapper.xml:

4. Create a new xml document called "Flow.xml" in the App_LocalResources folder of the HelloWorld web site and add the following element:

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 title="Detail Pages"> <siteMapNode url="RateCenterDetails.aspx" title="Rate Center Details" description="" />

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

9. Add the following member variables: private WebServiceController controller = new WebServiceController();

10. In CreateChildControls add the following after base.CreateChildControls is called: L3Form form = new L3Form();

72

try { int eid = Int32.Parse(Request.QueryString["ratecentereid"]); RateCenterVO rateCenter = controller.GetRateCentersByEid(eid); form.AddRow(HWValueMapper.Instance.GetLabelValue("ratecentereid"), L3ControlFactory.CreateLabel(rateCenter.rateCenterEid.ToString())); form.AddRow(HWValueMapper.Instance.GetLabelValue("rcabbrev"), L3ControlFactory.CreateLabel(rateCenter.rcAbbrev)); form.AddRow(HWValueMapper.Instance.GetLabelValue("stateabbrev"), L3ControlFactory.CreateLabel(rateCenter.stateAbbrev)); form.AddRow(HWValueMapper.Instance.GetLabelValue("taxationclli"), L3ControlFactory.CreateLabel(rateCenter.taxationClli)); form.AddRow(HWValueMapper.Instance.GetLabelValue("level3ocn"), L3ControlFactory.CreateLabel(rateCenter.level3Ocn.ToString())); form.AddRow(HWValueMapper.Instance.GetLabelValue("lata"), L3ControlFactory.CreateLabel(rateCenter.lata.ToString())); } catch (Exception ex) { ValidationManager.AddFailure("Failed to find rate center."); } L3ButtonPanel bp = new L3ButtonPanel(); bp.AddLeftControl(L3ControlFactory.CreateBackButton()); ValidationManager.AddInfo("This is an example of a details screen."); Controls.Add(L3Border.WrapControl(form, "Rate Center Details", L3Icon.PageDetails, bp));

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

73

Source File Code 6.5: HWGridDefinitions.xml <Parameter dataFieldKey="rateCenterEid" id="ratecentereid"/>

Source File Code 6.5: Web.sitemap <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 title="Detail Pages"> <siteMapNode url="RateCenterDetails.aspx" title="Rate Center Details" description="" />

Source File Code 6.5: RateCenterDetails.aspx.cs using using using using using using using

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

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

74

#region Control Overrides protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); } protected override void CreateChildControls() { base.CreateChildControls(); L3Form form = new L3Form(); try {

int eid = Int32.Parse(Request.QueryString["ratecentereid"]); RateCenterVO rateCenter =

g()));

controller.GetRateCentersByEid(eid);

form.AddRow(HWValueMapper.Instance.GetLabelValue("ratecentereid"), L3ControlFactory.CreateLabel(rateCenter.rateCenterEid.ToStrin

form.AddRow(HWValueMapper.Instance.GetLabelValue("rcabbrev"), L3ControlFactory.CreateLabel(rateCenter.rcAbbrev)); form.AddRow(HWValueMapper.Instance.GetLabelValue("stateabbrev"), L3ControlFactory.CreateLabel(rateCenter.stateAbbrev)); form.AddRow(HWValueMapper.Instance.GetLabelValue("taxationclli"), L3ControlFactory.CreateLabel(rateCenter.taxationClli)); form.AddRow(HWValueMapper.Instance.GetLabelValue("level3ocn"), L3ControlFactory.CreateLabel(rateCenter.level3Ocn.ToString())); form.AddRow(HWValueMapper.Instance.GetLabelValue("lata"), L3ControlFactory.CreateLabel(rateCenter.lata.ToString())); } catch (Exception ex) { ValidationManager.AddFailure("Failed to find rate center."); } L3ButtonPanel bp = new L3ButtonPanel(); bp.AddLeftControl(L3ControlFactory.CreateBackButton()); ValidationManager.AddInfo("This is an example of a details screen."); Controls.Add(L3Border.WrapControl(form, "Rate Center Details", L3Icon.PageDetails, bp)); } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); } }

#endregion

75

Module 7: HelloWorld Base Page and Using the Cornerstone SearchControl Module Goal:

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

76

Procedure 7.1: Creating the HelloWorld base page

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

4. Add the following using statements: using HelloWorld.Common; using Level3.Cornerstone.Common.ValueMapper; using Level3.Cornerstone.Web.WebControls;

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

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

77

Source File Code 7.1: HWPageBase.cs using HelloWorld.Common; using Level3.Cornerstone.Common.ValueMapper; using Level3.Cornerstone.Web.WebControls; /// <summary> /// Base page class for the HelloWorld web application /// public abstract class HWPageBase : L3PageTemplate { protected static IValueMapper Mapper { get { return HWValueMapper.Instance; } } }

78

Procedure 7.2: Creating the dedicated search control

1. 2. 3. 4. 5.

Create a folder called “WebControls” in the App_Code folder of the HelloWorld web site. Create a folder called “CriteriaControls” in the “WebControls” folder. Create a class file called “RateCenterSearchCriteriaControl.cs” in the WebControls folder. Make the class public and delete the default constructor. Add the using statements: using System.Collections; using System.Web.UI.WebControls; using HelloWorld.Common; using HelloWorld.Web.Controllers; using Level3.Cornerstone.Common.ValueMapper; using Level3.Cornerstone.Data; using Level3.Cornerstone.Web; using Level3.Cornerstone.Web.WebControls;

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

8. Add a private method called Populate with: private void Populate() { EnsureChildControls(); WebServiceController controller = new WebServiceController(); SortedList stateNames = controller.GetStates(); stateList.DataSource = stateNames; stateList.DataTextField = "value"; stateList.DataValueField = "key"; stateList.DataBind(); }

9. Override the CreateChildControls: protected override void CreateChildControls() { base.CreateChildControls(); stateList = L3ControlFactory.CreateListBox(); rcAbbrevTextBox = new L3TextBox(); lataTextBox = new L3TextBox(); L3Form form = new L3Form(); form.AddRow(mapper.GetLabelValue("stateabbrev"), stateList); form.AddRow(mapper.GetLabelValue("rcabbrev"), rcAbbrevTextBox); form.AddRow(mapper.GetLabelValue("lata"), lataTextBox); Controls.Add(form); if (!Page.IsPostBack)

79

{ Populate(); } }

10. Override the Criteria property with: public override SearchCriteria Criteria { get { SearchCriteria criteria = new SearchCriteria(); criteria.Add("stateabbrev", SearchCriteriaValue.Create(stateList.SelectedValue)); criteria.Add("rcabbrev", SearchCriteriaValue.Create(rcAbbrevTextBox.Text)); criteria.Add("lata", SearchCriteriaValue.Create(lataTextBox.Text)); return criteria; } set { WebUtil.SelectItemsByValue(stateList, value["stateabbrev"].Value as string); rcAbbrevTextBox.Text = (string)value["rcabbrev"].Value; lataTextBox.Text = (string)value["lata"].Value; } }

11. Save and build the solution.

80

Source File Code 7.2: RateCenterSearchCriteriaControl.cs using using using using using using using

System.Collections; System.Web.UI.WebControls; HelloWorld.Web.Controllers; Level3.Cornerstone.Common.ValueMapper; Level3.Cornerstone.Data; Level3.Cornerstone.Web; Level3.Cornerstone.Web.WebControls;

/// <summary> /// Summary description for RateCenterSearchCriteriaControl /// 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)); } set { string);

return criteria;

WebUtil.SelectItemsByValue(stateList, value["stateabbrev"].Value as rcAbbrevTextBox.Text = (string)value["rcabbrev"].Value;

81

}

lataTextBox.Text = (string)value["lata"].Value;

} private void Populate() { EnsureChildControls(); WebServiceController controller = new WebServiceController(); SortedList stateNames = controller.GetStates(); stateList.DataSource = stateNames; stateList.DataTextField = "value"; stateList.DataValueField = "key"; stateList.DataBind(); }

}

82

Procedure 7.3: Creating the search controller

1. Add a reference to Level3.Cornerstone.Data.dll to the HelloWorld.Web.Controllers project. 2. Add the following method to WebServiceController.cs in the HelloWorldWebControllers project: public RateCenterVO[] GetRateCentersByExample(RateCenterVO criteria) { RateCenterVO rateCenter = EmptyRateCenterVO ; if (criteria.stateAbbrev != null) { rateCenter.stateAbbrev = criteria.stateAbbrev; } if (criteria.rcAbbrev != null) { rateCenter.rcAbbrev = criteria.rcAbbrev; } if (criteria.lata != -1) { rateCenter.lata = criteria.lata; } RateCenterVO[] rateCenterResults = webService.FindAllRateCenter(rateCenter); return rateCenterResults; }

3. Create the class RateCenterSearchController.cs in the HelloWorld.Web.Controllers project. 4. Add the using statements: using System; using HelloWorld.Services.WebServices.TAI.Maint; using Level3.Cornerstone.Data; using Level3.Cornerstone.Web.WebControls;

5. Make the class public. 6. Add the private member variable: private WebServiceController controller;

7. Add the two public contructors: public RateCenterSearchController() : this(new WebServiceController()) { } public RateCenterSearchController(WebServiceController controller) { this.controller = controller; }

8. Implement the DoSearch method with: protected override SearchResult DoSearch(SearchCriteria criteria) { // This is a data mapping step and could be implemented as a dedicated data mapping routine.

83

RateCenterVO example = WebServiceController. BuildEmptyRateCenterVO(); if (criteria["rcabbrev"] != null && !String.IsNullOrEmpty((string)criteria["rcabbrev"].Value)) { example.rcAbbrev = (string) criteria["rcabbrev"].Value; } if (criteria["stateabbrev"] != null && !String.IsNullOrEmpty((string)criteria["stateabbrev"].Value)) { example.stateAbbrev = (string)criteria["stateabbrev"].Value; } if (criteria["lata"] != null && !String.IsNullOrEmpty((string)criteria["lata"].Value)) { example.lata = Int32.Parse((string)criteria["lata"].Value); } RateCenterVO[] rateCenterResponses = controller.GetRateCentersByExample(example); SearchResult result = new SearchResult(rateCenterResponses); return result; }

9. Save all files and rebuild the solution.

84

Source File Code 7.3: RateCenterSearchController.cs using using using using

System; HelloWorld.Services.WebServices.TAI.Maint; Level3.Cornerstone.Data; Level3.Cornerstone.Web.WebControls;

namespace HelloWorld.Web.Controllers { public class RateCenterSearchController : SearchController { private WebServiceController controller; public RateCenterSearchController() : this(new WebServiceController()) {} public RateCenterSearchController(WebServiceController controller) { this.controller = controller; } protected override SearchResult DoSearch(SearchCriteria criteria) { // This is a data mapping step and could be implemented as a dedicated data mapping routine. RateCenterVO example = WebServiceController.EmptyRateCenterVO; if (criteria["rcabbrev"] != null && ! String.IsNullOrEmpty((string)criteria["rcabbrev"].Value)) { example.rcAbbrev = (string)criteria["rcabbrev"].Value; } if (criteria["stateabbrev"] != null && ! String.IsNullOrEmpty((string)criteria["stateabbrev"].Value)) { example.stateAbbrev = (string)criteria["stateabbrev"].Value; } if (criteria["lata"] != null && ! String.IsNullOrEmpty((string)criteria["lata"].Value)) { example.lata = Int32.Parse((string)criteria["lata"].Value); } RateCenterVO[] rateCenterResponses = controller.GetRateCentersByExample(example); SearchResult result = new SearchResult(rateCenterResponses); return result; }

}

}

85

Procedure 7.4: Creating the search page with the RateCenterSearchCriteriaControl

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

4. Add the private member variables: private SearchCriteriaControl criteriaControl; private GridViewDefinition gridDefinition; private SearchController searchController;

5. Add the following to CreateChildControls after the base CreateChildControls is called: criteriaControl = new RateCenterSearchCriteriaControl(); gridDefinition = HWGridViewFactory.Create("ratecentergriddef"); searchController = new RateCenterSearchController(); SearchControl searchControl = new SearchControl(criteriaControl, searchController, gridDefinition); ValidationManager.AddInfo("Web service search example using the search control."); Controls.Add(searchControl);

6. Save and browse WebService3.aspx.

86

Source File Code 7.4: WebService3.aspx.cs using using using using using

System; HelloWorld.Common; HelloWorld.Web.Controllers; Level3.Cornerstone.Web.WebControls; Level3.Cornerstone.Web.WebControls.Validation;

/// <summary> /// Summary description for WebService3 /// Cornerstone Enabled Web Form /// public partial class WebService3 : HWPageBase { #region Attributes private SearchCriteriaControl criteriaControl; private GridViewDefinition gridDefinition; private SearchController searchController; #endregion #region Control Overrides protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); } protected override void CreateChildControls() { base.CreateChildControls(); criteriaControl = new RateCenterSearchCriteriaControl(); gridDefinition = HWGridViewFactory.Create("ratecentergriddef"); searchController = new RateCenterSearchController(); SearchControl searchControl = new SearchControl(criteriaControl, searchController, gridDefinition); ValidationManager.AddInfo("Web service search example using the search control."); Controls.Add(searchControl); } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e);

}

if (!Page.IsPostBack) { }

#endregion }

87

Module 8: Consuming Data from a Database Module Goal:

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

88

Procedure 8.1: Adding a datasource and creating the DAO

1. Open web.config and add the following element to the element:

2. 3. 4. 5. 6.

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

7. Create the private member variables: private L3Database db; private readonly string tableName = "AUDIT_SERVICE";

8. Create the two constructors: public UnifiedAuditingDao() : this(new L3Database("INFSENV1")) { } public UnifiedAuditingDao(L3Database db) { this.db = db; }

9. Add the two public methods: public SearchResult Search(SearchCriteria searchCriteria) { return Search(searchCriteria, tableName, HelloWorld.Common.HWValueMapper.Instance, false); } public SearchResult Search(SearchCriteria searchCriteria, string table, IValueMapper mapper, bool createIds) { SearchResult result = new SearchResult(); DataSet dataSet = db.ExecuteDataSet(table, searchCriteria, mapper); if (createIds) { DataUtil.AddIdColumn(dataSet.Tables[0]); } result.Data = dataSet; result.TotalRows = dataSet.Tables[0].Rows.Count; return result; }

89

10. Save and build the HelloWorld.Services project.

90

Source File Code 8.1: UnifiedAuditingDao.cs using System.Data; using Level3.Cornerstone.Common.ValueMapper; using Level3.Cornerstone.Data; namespace HelloWorld.Services.DataAccess { public class UnifiedAuditingDao { private L3Database db; private readonly string tableName = "AUDIT_SERVICE"; public UnifiedAuditingDao() : this(new L3Database("INFSENV1")) { } public UnifiedAuditingDao(L3Database db) { this.db = db; } public SearchResult Search(SearchCriteria searchCriteria) { return Search(searchCriteria, tableName, HelloWorld.Common.HWValueMapper.Instance, false); } public SearchResult Search(SearchCriteria searchCriteria, string table, IValueMapper mapper, bool createIds) { SearchResult result = new SearchResult(); DataSet dataSet = db.ExecuteDataSet(table, searchCriteria, mapper); if (createIds) { DataUtil.AddIdColumn(dataSet.Tables[0]); } result.Data = dataSet; result.TotalRows = dataSet.Tables[0].Rows.Count; } }

return result;

}

91

Procedure 8.2: Creating the UnifiedAuditingSearchController, gridview definition, UnifiedAuditingSearchCriteriaControl, and search page

(Note: The steps to build these files have been covered in Procedure 7 so the whole contents of each file will be listed here and not built up in steps.) 1. Add a reference to Level3.Cornerstone.Common.dll, System.Web, and HelloWorld.Common to the HelloWorld.Web.Controllers project. 2. Create the class UnifiedAuditingSearchController in the HelloWorld.Web.Controllers project and add/change the code to: using System; using System.Data; using System.Web; using HelloWorld.Common; using HelloWorld.Services.DataAccess; using Level3.Cornerstone.Data; using Level3.Cornerstone.Web.WebControls; using Level3.Cornerstone.Common.ValueMapper; using Level3.Cornerstone.Web.WebControls.Validation; namespace HelloWorld.Web.Controllers { public class UnifiedAuditingSearchController : SearchController { #region Class Attributes private readonly IValueMapper mapper = HWValueMapper.Instance; private readonly UnifiedAuditingDao dao; #endregion #region Constructors public UnifiedAuditingSearchController() { dao = new UnifiedAuditingDao(); } #endregion protected override SearchResult DoSearch(SearchCriteria searchCriteria) { SearchResult results = new SearchResult(); try { results = dao.Search(searchCriteria); } catch (Exception ex) { ValidationManager.AddFailure(ex.Message); } return FormatXmlFields(results); } private SearchResult FormatXmlFields(SearchResult result) {

92

DataSet dataSet = result.Data; if (dataSet.Tables.Count > 0) { DataTable dataTable = dataSet.Tables[0]; foreach (DataRow resultRow in dataTable.Rows) { string requestXml = resultRow["REQUEST_DATA"].ToString(); resultRow["REQUEST_DATA"] = HttpUtility.HtmlEncode(requestXml); string responseXml = resultRow["RESPONSE_DATA"].ToString(); resultRow["RESPONSE_DATA"] = HttpUtility.HtmlEncode(responseXml); } } return result; } } }

3. Add the following GridView definition to HWGridDefinitions.xml in the HelloWorld web site:

4. Add the class “UnifiedAuditingSearchCriteriaControl” to the HelloWorld web site under the App_Code WebControlsCriteriaControls folder and add/change its code to: using System.Web.UI.WebControls; using HelloWorld.Common; using Level3.Cornerstone.Common; using Level3.Cornerstone.Common.ValueMapper; using Level3.Cornerstone.Data; using Level3.Cornerstone.Web; using Level3.Cornerstone.Web.WebControls; /// <summary> /// Summary description for UnifiedAuditingSearchCriteriaControl /// public class UnifiedAuditingSearchCriteriaControl : SearchCriteriaControl { private TextBox auditServiceIdTextBox; private DateRangeControl auditTimestampDateRange; private ListBox sourceApplicationListBox; private TextBox operationNameTextBox; private TextBox requestDataTextBox; private TextBox responseDataTextBox;

93

private TextBox classNameTextBox; private TextBox correlationIdTextBox; private TextBox errorCodeTextBox; private TextBox errorMessageTextBox; private IValueMapper mapper = HWValueMapper.Instance; #region Control Overrides protected override void CreateChildControls() { base.CreateChildControls(); auditServiceIdTextBox = L3ControlFactory.CreateTextBox(); auditTimestampDateRange = new DateRangeControl(); sourceApplicationListBox = L3ControlFactory.CreateListBox(); operationNameTextBox = L3ControlFactory.CreateTextBox(); requestDataTextBox = L3ControlFactory.CreateTextBox(); responseDataTextBox = L3ControlFactory.CreateTextBox(); classNameTextBox = L3ControlFactory.CreateTextBox(); correlationIdTextBox = L3ControlFactory.CreateTextBox(); errorCodeTextBox = L3ControlFactory.CreateTextBox(); errorMessageTextBox = L3ControlFactory.CreateTextBox(); L3Form form = new L3Form(); Controls.Add(form); L3Form leftForm = new L3Form(); leftForm.AddRow(mapper.GetLabelValue("correlationid"), correlationIdTextBox); leftForm.AddRow(mapper.GetLabelValue("sourceapplication"), sourceApplicationListBox); leftForm.AddRow(mapper.GetLabelValue("audittimestamp"), auditTimestampDateRange); L3Form rightForm = new L3Form(); rightForm.AddRow(mapper.GetLabelValue("operationname"), operationNameTextBox); rightForm.AddRow(mapper.GetLabelValue("requestdata"), requestDataTextBox); rightForm.AddRow(mapper.GetLabelValue("responsedata"), responseDataTextBox); rightForm.AddRow(mapper.GetLabelValue("classname"), classNameTextBox); rightForm.AddRow(mapper.GetLabelValue("auditserviceid"), auditServiceIdTextBox); rightForm.AddRow(mapper.GetLabelValue("errorcode"), errorCodeTextBox); rightForm.AddRow(mapper.GetLabelValue("errormessage"), errorMessageTextBox); form.AddRow(leftForm, rightForm); if (Page.IsPostBack == false) { PopulateDropDowns(); } } #endregion public override SearchCriteria Criteria { get { EnsureChildControls(); SearchCriteria criteria = new SearchCriteria();

94

criteria.Add("correlationid", SearchCriteriaValue.Create(correlationIdTextBox.Text)); criteria.Add("sourceapplication", SearchCriteriaValue.Create(sourceApplicationListBox.SelectedValue)); criteria.Add("audittimestamp", SearchCriteriaValue.CreateDateRange(auditTimestampDateRange.Range)); criteria.Add("operationname", SearchCriteriaValue.CreateLike(operationNameTextBox.Text, 100)); criteria.Add("requestdata", SearchCriteriaValue.CreateLike(requestDataTextBox.Text, 100)); criteria.Add("responsedata", SearchCriteriaValue.CreateLike(responseDataTextBox.Text, 100)); criteria.Add("classname", SearchCriteriaValue.CreateLike(classNameTextBox.Text, 100)); criteria.Add("auditserviceid", SearchCriteriaValue.Create(auditServiceIdTextBox.Text)); criteria.Add("errorcode", SearchCriteriaValue.Create(errorCodeTextBox.Text)); criteria.Add("errormessage", SearchCriteriaValue.CreateLike(errorMessageTextBox.Text, 100)); return criteria; } set { EnsureChildControls(); sourceApplicationListBox.SelectedValue = value.Get("sourceapplication").Value as string; correlationIdTextBox.Text = value.Get("correlationid").Value as string; auditTimestampDateRange.Range = value.Get("audittimestamp").Value as DateRange; operationNameTextBox.Text = value.Get("operationname").Value as string; requestDataTextBox.Text = value.Get("requestdata").Value as string; responseDataTextBox.Text = value.Get("responsedata").Value as string; classNameTextBox.Text = value.Get("classname").Value as string; auditServiceIdTextBox.Text = value.Get("auditserviceid").Value as string; errorCodeTextBox.Text = value.Get("errorcode").Value as string; errorMessageTextBox.Text = value.Get("errormessage").Value as string; } } private void PopulateDropDowns() { WebUtil.Populate(sourceApplicationListBox, mapper.GetGroup("sourceapplicationgroup"), true); } }

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

6. The following elements inside the element of HWValueMapper.xml (note: the dtoValue attribute is not used during this module but may be used in later modules):

95



7. Create a new Cornerstone web page called “DataAccess1.aspx” in the HelloWorld web site and add/change the code in the code-behind to: using System; using HelloWorld.Common; using HelloWorld.Web.Controllers; using Level3.Cornerstone.Web.WebControls; using Level3.Cornerstone.Web.WebControls.Validation; public partial class DataAccess1 : HWPageBase { private SearchCriteriaControl criteriaControl; private GridViewDefinition gridDefinition; private SearchController searchController; protected override void OnInit(EventArgs e) { base.OnInit(e); EnsureChildControls(); ValidationManager.AddInfo("Database search example using grid view and the search control."); } protected override void CreateChildControls() { base.CreateChildControls(); criteriaControl = new UnifiedAuditingSearchCriteriaControl(); gridDefinition = HWGridViewFactory.Create("unifiedauditinggriddef"); searchController = new UnifiedAuditingSearchController(); SearchControl searchControl = new SearchControl(criteriaControl, searchController, gridDefinition); Controls.Add(searchControl); } }

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

96

Advanced Topics • • • • • • • • • • • •

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

Appendix: Coding Standards Reference the Coding Standards document on the Cornerstone Sharepoint site

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

97

Related Documents

Cornerstone Training
October 2019 12
Cornerstone
May 2020 16
Cornerstone
June 2020 8
Cornerstone In Bm
October 2019 11