Академический Документы
Профессиональный Документы
Культура Документы
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.
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 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
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();
}
10
Source File Code 1.2: HelloWorldPage.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="HelloWorldPage.aspx.cs"
Inherits="HelloWorldPage" %>
11
Procedure 1.3: Adding a Header, Footer, and Style Sheet
1. Create a folder in the web site called "Styles"
2. Add the file HelloWorldStyle.css to the Styles folder from the location your instructor gives you.
3. Open Web.config and add the following under the line "</configSections>"
<!-- Cornerstone specific settings -->
<appSettings>
<!-- Location of the Header Control to use for the template -->
<add key="HeaderControlLocation" value="UserControls/Header.ascx"/>
<!-- Location of the Footer Control to use for the template -->
<add key="FooterControlLocation" value="UserControls/Footer.ascx"/>
</appSettings>
4. Right click the HelloWorld web site and select "New Folder"
5. Rename the new folder "UserControls". This is where the header and footer for the application pages
will be kept.
6. Right click the "UserControls" folder and select "Add New Item…"
7. Add a "Web User Control" called "Header.ascx"
8. Repeat the previous two steps to add "Footer.ascx"
9. Add the following to Header.ascx source view
10. Open the source view for Header.ascx and add the following to the end of the file:
<link href="Styles/HelloWorldStyle.css" rel="stylesheet" type="text/css">
<div id="headerFrame"> HelloWorld Header </div>
11. Open the source view for Footer.ascx and add the following to the end of the file:
<div id="footerFrame"> HelloWorld Footer </div>
12
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>
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
return instance;
}
}
10. Right click the Common project and build the project.
16
Source File Code 2.1: HWValueMapper.cs
using System.IO;
using System.Web;
using Level3.Cornerstone.Common.ValueMapper;
namespace HelloWorld.Common
{
/// <summary>
/// Singleton Wrapper on <see cref="IValueMapper"/>
/// </summary>
public class HWValueMapper
{
private static IValueMapper instance;
private HWValueMapper()
{
}
return instance;
}
}
}
}
17
Procedure 2.2: Creating the ValueMapper resource file
1. Right-click the HelloWorld_Solution web site, and select "App_LocalResources" the "Add ASP.NET
Folder" menu.
2. Right click the "App_LocalResources folder and add an XML file called HWValueMapper.xml.
3. Add the following line to the bottom of HWValueMapper.xml:
<Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">
<Values>
<ValueItem key="helloworld" presentationValue="Hello World! (from the Value Mapper)"/>
</Values>
</Mapping>
18
Source File Code 2.2: HWValueMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">
<Values>
<ValueItem key="helloworld" presentationValue="HelloWorld!(from the Value
Mapper)"/>
</Values>
</Mapping>
19
Procedure 2.3: Using the ValueMapper in HelloWorldPage
1. Add a reference to the HelloWorld.Common project to the HelloWorld web site.
2. Open HelloWorld.aspx.cs
3. Add "using HelloWorld.Common;"
4. Add a line break and a label to the pages Control collection with the following lines in the
CreateChildControls method:
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentationValue("helloworld")));
20
Source File Code 2.3: HelloWorldPage.aspx.cs
using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.WebControls;
21
Module 3: Adding a Controller Project
Module Goal:
In this module we introduce the Controller layer which routes data between the UI and the service layers. We
will process and responds to events from the page. At the end of this module solution will have:
• A new class library project called Controller
• A controller class to hold logic for the HelloWorldPage
22
Procedure 3.1: Creating the HelloWorld.Web.Controllers project and adding a controller
1. Add a new class library project to the solution called HelloWorld.Web.Controllers on the path
c:\HelloWorld_Solution.
2. Delete the Class1.cs file in the new project.
3. Add a new class file called HelloWorldController.cs to the project.
4. Open the class file and make the class definition public.
5. Delete all of the "using" statements.
6. Create a public parameterless method in the HelloWorldController class called
GenerateHelloWorldDisplayText that returns the string "Hello World! (from the controller)"
7. Right click the HelloWorld.Web.Controllers project and build the project.
23
Source File Code 3.1: HelloWorldController.cs
namespace HelloWorld.Web.Controllers
{
public class HelloWorldController
{
public string GenerateHelloWorldDisplayText()
{
return "Hello World! (from the controller)"
}
}
}
24
Procedure 3.2: Using the HelloWorld Controller
1. Add a reference to the HelloWorld.Web.Controllers project to the HelloWorld web site.
2. Open the HelloWorldPage.aspx.cs file
3. Add the using statement "using HelloWorld.Web.Controllers;"
4. Add a member variable to the class called "controller" with the statement:
HelloWorldController controller = new HelloWorldController();
5. Add a line break and a label control to the page and use the method GenerateHelloWorldDisplayText
from the controller to fill the text.
6. Save and view the page in the browser.
25
Source File Code 3.2: HelloWorldPage.aspx.cs
using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.WebControls;
using HelloWorld.Web.Controllers;
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"));
28
Source File Code 4.1: HelloWorldPage.aspx.cs
using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.WebControls;
using HelloWorld.Web.Controllers;
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((L3ControlFactory.CreateLabel("Hello World")));
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(HWValueMapper.Instance.GetPresentat
ionValue("helloworld")));
Controls.Add(L3ControlFactory.CreateBreak());
Controls.Add(L3ControlFactory.CreateLabel(controller.GenerateHelloWorldDispla
yText()));
}
}
29
Procedure 4.2: Adding the L3ButtonPanel and Event Handlers
1. Add the following items to the HWValueMapper.xml:
<!-- Button Labels-->
<ValueItem key="getvalues" presentationValue="Get Values" />
<ValueItem key="clearvalues" presentationValue="Clear Values" />
<ValueItem key="submit" presentationValue="Submit" />
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);
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;
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
#endregion
11. Create the InitializeValues method which resets the values of the labels:
private void InitializeValues()
{
helloWorldFromValueMapper.Text = "Click 'Get Values' to retrieve this.";
helloWorldFromController.Text = "Click 'Get Values' to retrieve this.";
}
12. Override the base pages OnPreRender event with the following (for organization purposes put this
method below the OnInit method):
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (!Page.IsPostBack)
{
InitializeValues();
}
}
13. Save and browse the page. Click the two new buttons to make sure they both work.
31
Source File Code 4.2: HWValueMapper.xml
<?xml version="1.0" encoding="utf-8" ?>
<Mapping xmlns="http://www.level3.com/dotnetcommon/ValueMapperSchema.xsd">
<Values>
<ValueItem key="helloworld" presentationValue="HelloWorld! (from the Value
Mapper)"/>
</Values>
</Mapping>
if (!Page.IsPostBack)
{
InitializeValues();
}
}
32
getValuesButton.Click += getValuesButton_Click;
Button clearValuesButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("clearvalue
s"));
clearValuesButton.Click += clearValuesButton_Click;
buttonPanel.AddRightControl(getValuesButton);
buttonPanel.AddRightControl(clearValuesButton);
#endregion
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.");
5. Save and browse the page. Click on the buttons to see how the ValidationManager is displayed.
34
Source File Code: HelloWorldPage.aspx.cs
using System;
using HelloWorld.Common;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using HelloWorld.Web.Controllers;
using System.Web.UI.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;
if (!Page.IsPostBack)
{
InitializeValues();
}
}
Button clearValuesButton =
L3ControlFactory.CreateButton(HWValueMapper.Instance.GetPresentationValue("clearvalue
s"));
clearValuesButton.Click += clearValuesButton_Click;
buttonPanel.AddRightControl(getValuesButton);
buttonPanel.AddRightControl(clearValuesButton);
#endregion
36
Module 5: Consuming Web Services
Module Goal:
In this module we will build a new project for consuming web services which utilizes the Level 3 UDDI
registry to different environments. We also establish the pattern of using an Interface to the web service which
allows us to create unit tests and stubs for the web service. At the end of the module the HelloWorld solution
will have:
• New HelloWorld.Services project for consuming web services
• A web reference to web services in the application TAI
• A ServiceFactory (see Architecture Overview section)
• An Interface definition for the TAI web service
• A stub for the TAI web service to use during development when the TAI service is not available
• A new page that populates a drop down list with data from the TAI web service
37
Procedure 5.1: Creating the HelloWorld.Services project and web reference
1. Create a new class library project in c:\HelloWorld_Solution called HelloWorld.Services.
2. Delete the file Class1.cs
3. Add references to Level3.Cornerstone.UDDIRegistry.dll and Level3.Cornerstone.Common from the
distribution folder.
4. Add the following to web.config under the node <configuration>:
<configSections>
<section name="ServiceProperties" type="Blank"/>
<section name="uddiConfiguration"
type="Level3.Cornerstone.UDDIRegistry.Configuration.UDDIRegistrySection, Level3.Cornerstone.UDDIRegistry,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</configSections>
5. Add the following to web.config above the node </configuration>. These values are used later to point at
the different environments where the web services are published:
<uddiConfiguration registryUrl="http://registry.env1.level3.com/registryservice/RegistryQueryService"
environment="ENV1" cacheTimeoutSeconds="3600">
<services>
<add name="TAI_WebServices"
registryServiceName="http://level3.com/enterprise/network_activation/tai/maint" contact="Schneider,
Kevin" provider="TAI"/>
</services>
</uddiConfiguration>
<ServiceProperties>
<ServiceItem name="TaiWebService" mockOn="false"/>
</ServiceProperties>
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;
public TaiWebService()
{
service = new TAI_WebServices();
IRegistry registry = RegistryManager.Load();
registry.Bind(serviceName, service);
}
8. Add the LocStateObjConverter method to convert the generic objects returned by the TAI web service to
LocStateVOs:
public static LocStateVO LocStateObjectConverter(object obj)
{
return (LocStateVO)obj;
}
41
Source File Code 5.3: TaiWebService.cs
using System;
using System.Web.Services.Protocols;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.UDDIRegistry;
namespace HelloWorld.Services.WebServices
{
public class TaiWebService : ITaiWebService
{
private string serviceName = typeof(TAI_WebServices).Name;
private SoapHttpClientProtocol service;
public TaiWebService()
{
service = new TAI_WebServices();
IRegistry registry = RegistryManager.Load();
registry.Bind(serviceName, service);
}
#endregion
#region Converters
#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;
return locStates;
}
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
#endregion
#region Helpers
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.
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()
{
}
/// <summary>
/// Creates the correct ServiceFactory based on the type.
/// </summary>
public class CSTServiceFactory : IServiceFactory
{
Dictionary<Type, ServiceFactory> serviceDictionary = new Dictionary<Type, ServiceFactory>();
internal CSTServiceFactory()
{
// Include code here to handle every service type.
serviceDictionary.Add(typeof(ITaiWebService), new
ServiceFactory(ServiceTypes.TaiWebService.ToString(), typeof(TaiWebService), typeof(TaiWebServiceStub)));
}
45
public ServiceFactory Create(object serviceType)
{
Type t = (Type)serviceType;
if (!serviceDictionary.ContainsKey(t))
{
throw new Exception(BuildErrorMessage(t.Name));
}
return serviceDictionary[t];
}
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;
7. Add the following public method (GetStates) and property (EmptyLocStateVO) to the class:
return stateList;
}
catch (Exception ex)
{
ValidationManager.AddFailure("GetStateNameAbbreviations failed: " + ex.Message);
return new SortedList();
}
}
48
Source File Code 5.6: WebServiceController.cs
using System;
using System.Collections;
using HelloWorld.Services;
using HelloWorld.Services.WebServices;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.Web.WebControls.Validation;
namespace HelloWorld.Web.Controllers
{
public class WebServiceController
{
private ITaiWebService webService;
#region Constructors
public WebServiceController()
: this(CSTServicesFactory.Create<ITaiWebService>())
{
}
#endregion
#region Members
public SortedList GetStates()
{
try
{
LocStateVO[] locStates =
webService.FindAllLocState(EmptyLocStateVO());
return stateList;
}
catch (Exception ex)
{
ValidationManager.AddFailure("GetStateNameAbbreviations failed: " +
ex.Message);
return new SortedList();
}
}
50
Procedure 5.7: Populating a drop down list with data from the TAI web service
1. Add a new Cornerstone web page from the template to the HelloWorld web site called
WebService1.aspx.
2. Add a ValueItem to HWValueMapper.xml with:
<ValueItem key="statelist" presentationValue="States" />
3. Open the code behind file for the new WebService1.aspx and change the using statements to:
using System;
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;
6. In the OnInit event, instantiate the controller before the base OnInit method is called:
controller = new WebServiceController();
stateList.DataSource = states;
stateList.DataTextField = "value";
stateList.DataValueField = "key";
stateList.DataBind();
}
}
52
Source File Code 5.7: WebService1.aspx.cs
using System;
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;
#endregion
base.OnInit(e);
EnsureChildControls();
}
if (!IsPostBack)
{
PopulateDropDowns();
}
}
stateList = L3ControlFactory.CreateDropDown();
#endregion
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;
}
return rcs;
}
56
rateCenterVo.lata = id;
rateCenterVo.level3Ocn = id;
rateCenterVo.lastUpdateDate = DateTime.Now.ToString();
rateCenterVo.lastUpdateUser = "User-" + id;
rateCenterVo.taxationClli = "taxCLLI-" + id;
return rateCenterVo;
}
return retVO;
}
}
return rateCenterResults;
}
return rateCenterResult;
}
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);
}
}
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);
}
#endregion
#region Converters
58
public static LocStateVO LocStateObjectConverter(object obj)
{
return (LocStateVO)obj;
}
#endregion
}
}
namespace HelloWorld.Services.Stubs
{
public class TaiWebServiceStub : ITaiWebService
{
#region ITaiWebService Members
return rcs;
}
#endregion
#region Helpers
return locStateVo;
}
return rateCenterVo;
}
#endregion
}
}
namespace HelloWorld.Web.Controllers
{
public class WebServiceController
{
private ITaiWebService webService;
#region Constructors
public WebServiceController()
: this(CSTServicesFactory.Create<ITaiWebService>())
{
}
#endregion
#region Members
public SortedList GetStates()
{
try
60
{
LocStateVO[] locStates =
webService.FindAllLocState(EmptyLocStateVO);
return stateList;
}
catch (Exception ex)
{
ValidationManager.AddFailure("GetStateNameAbbreviations failed: " +
ex.Message);
return new SortedList();
}
}
rateCenter.stateAbbrev = stateAbbrev;
RateCenterVO[] rateCenterResults =
webService.FindAllRateCenter(rateCenter);
return rateCenterResults;
}
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;
}
}
61
//The web service expects a null for "unset" integers, but .NET
//doesn't allow this. Compromise: Set INT fields equal to -1
//the service will read these as null
get
{
RateCenterVO retVO = new RateCenterVO();
retVO.level3Ocn = -1;
retVO.lata = -1;
retVO.rateCenterEid = -1;
retVO.tnCoverageOcn = -1;
retVO.sequenceLock = -1;
return retVO;
}
}
#endregion
}
}
62
Procedure 6.2: Creating the GridViewFactory and a GridView definition
1. Add a reference to Cornerstone.Web.dll in the HelloWorld.Common project.
2. Create a new class file in the HelloWorld.Common project called HWGridViewFactory.cs
3. Replace all the code in the HWGridViewFactory.cs with the following:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using Level3.Cornerstone.Web.WebControls;
namespace HelloWorld.Common
{
/// <summary>
/// Creates data grid defs from the xml file GridDefinitions.xml
/// </summary>
public static class HWGridViewFactory
{
#region private members
#endregion
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">
63
</Definitions>
6. Add the following values to HWValueMapper.xml under the Values element:
<ValueItem key="submit" presentationValue="Submit" />
64
Source File Code 6.2: HWGridViewFactory.cs
using System.IO;
using System.Web;
using Level3.Cornerstone.Web.WebControls;
namespace HelloWorld.Common
{
/// <summary>
/// Creates data grid defs from the xml file GridDefinitions.xml
/// </summary>
public static class HWGridViewFactory
{
#region private members
#endregion
return factory.Create(name);
}
}
}
</Definitions>
65
Procedure 6.3: Creating the Rate Center search page
1. Add a new web page called "WebService2" using the CornerstonePage template.
2. Open WebService2.aspx.cs and set the following "using" statements:
using System;
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Services.WebServices.TAI.Maint;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;
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;
}
66
Controls.Add(criteriaBorder);
Controls.Add(resultsBorder);
if (autoCollapseCriteria)
{
criteriaBorder.Collapsed = true;
}
}
}
9. Save all files rebuild the solution and browse the WebService2.aspx page.
67
Source File Code 6.3: WebService2.xml
using System;
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Services.WebServices.TAI.Maint;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.Images;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;
/// <summary>
/// Summary description for WebService2
/// Cornerstone Enabled Web Form
/// </summary>
public partial class WebService2 : L3PageTemplate
{
#region Attributes
private bool autoCollapseCriteria = true;
#endregion
base.OnInit(e);
EnsureChildControls();
}
stateList = L3ControlFactory.CreateDropDown();
L3Form form = new L3Form();
form.AddRow(HWValueMapper.Instance.GetLabelValue("statelist"), stateList);
GridViewDefinition rateCenterGridView =
HWGridViewFactory.Create("ratecentergriddef");
68
resultsGrid = L3GridView.Create(rateCenterGridView, true);
resultsBorder = L3Border.WrapControl(resultsGrid, "Rate Center Results");
Controls.Add(criteriaBorder);
Controls.Add(resultsBorder);
}
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
if (autoCollapseCriteria)
{
criteriaBorder.Collapsed = true;
}
}
}
69
private void PopulateDropDowns()
{
SortedList states = controller.GetStates();
#endregion
}
70
Procedure 6.4: Adding export and paging to the rate center grid
1. Open WebService2.aspx.cs.
2. In the CreateChildControls the line
resultsGrid = L3GridView.Create(rateCenterGridView, true);
to
resultsGrid = L3GridView.Create(rateCenterGridView, true, 10);
3. Save and browse the page. The grid will now have a paging bar at the top. Each page will contain 10
rows.
4. Add the following statement:
resultsGrid.ExportEnabled = true;
5. Save and browse the page. Notice the grid now has an export to Excel option.
6. Add the statements:
resultsGrid.CheckBoxColumnDataField = "rateCenterEid";
resultsGrid.AutoGenerateCheckBoxColumn = true;
7. Save and browse the page. The grid will now have a checkbox column and a "Export Selected" option.
Note: The same results can be obtained by removing these two statements and adding
"checkBoxDataFieldKey="rateCenterEid" to the GridView definition in HWGridDefinitions.
71
Procedure 6.5: Creating the Rate Center detail page
1. Open HWGridDefinitions.xml and add the following element to the definition of the "ratecentergriddef"
which adds an action icon to the GridView and defines which page the request will be routed to when
the user clicks the action icon:
<Actions>
<RedirectAction icon="PageGo" pageId="rateCenterDetails" toolTipKey="ratecenterdetails">
<Parameter dataFieldKey="rateCenterEid" id="ratecentereid"/>
</RedirectAction>
</Actions>
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;
72
try
{
int eid = Int32.Parse(Request.QueryString["ratecentereid"]);
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.");
}
11. Save all files, browse WebService2.aspx, get the Rate Centers for a state and select the Rate Center
Details icon in the grid.
73
Source File Code 6.5: HWGridDefinitions.xml
<?xml version="1.0" encoding="utf-8" ?>
<Definitions xmlns="http://www.level3.com/Cornerstone/GridDefinitionSchema.xsd">
</Definitions>
/// <summary>
/// Summary description for RateCenterDetails
/// Cornerstone Enabled Web Form
/// </summary>
public partial class RateCenterDetails : L3PageTemplate
{
#region Attributes
private WebServiceController controller = new WebServiceController();
#endregion
74
#region Control Overrides
try
{
int eid = Int32.Parse(Request.QueryString["ratecentereid"]);
form.AddRow(HWValueMapper.Instance.GetLabelValue("ratecentereid"),
L3ControlFactory.CreateLabel(rateCenter.rateCenterEid.ToStrin
g()));
form.AddRow(HWValueMapper.Instance.GetLabelValue("rcabbrev"),
L3ControlFactory.CreateLabel(rateCenter.rcAbbrev));
form.AddRow(HWValueMapper.Instance.GetLabelValue("stateabbrev"),
L3ControlFactory.CreateLabel(rateCenter.stateAbbrev));
form.AddRow(HWValueMapper.Instance.GetLabelValue("taxationclli"),
L3ControlFactory.CreateLabel(rateCenter.taxationClli));
form.AddRow(HWValueMapper.Instance.GetLabelValue("level3ocn"),
L3ControlFactory.CreateLabel(rateCenter.level3Ocn.ToString()));
form.AddRow(HWValueMapper.Instance.GetLabelValue("lata"),
L3ControlFactory.CreateLabel(rateCenter.lata.ToString()));
}
catch (Exception ex)
{
ValidationManager.AddFailure("Failed to find rate center.");
}
#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
7. From now on our solutions pages will inherit from this base page class and will automatically have an
instance of the HWValueMapper available to it. Other uses for this base class include logging, session
management, and navigation..
77
Source File Code 7.1: HWPageBase.cs
using HelloWorld.Common;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Web.WebControls;
/// <summary>
/// Base page class for the HelloWorld web application
/// </summary>
public abstract class HWPageBase : L3PageTemplate
{
protected static IValueMapper Mapper
{
get { return HWValueMapper.Instance; }
}
}
78
Procedure 7.2: Creating the dedicated search control
1. Create a folder called “WebControls” in the App_Code folder of the HelloWorld web site.
2. Create a folder called “CriteriaControls” in the “WebControls” folder.
3. Create a class file called “RateCenterSearchCriteriaControl.cs” in the WebControls folder.
4. Make the class public and delete the default constructor.
5. Add the using statements:
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web;
using Level3.Cornerstone.Web.WebControls;
6. Make the class inherit from the Cornerstone base class SearchCriteriaControl
7. Add the following private variables:
private L3ListBox stateList;
private TextBox rcAbbrevTextBox;
private TextBox lataTextBox;
private IValueMapper mapper = CSTHWValueMapper.Instance;
stateList.DataSource = stateNames;
stateList.DataTextField = "value";
stateList.DataValueField = "key";
stateList.DataBind();
}
stateList = L3ControlFactory.CreateListBox();
rcAbbrevTextBox = new L3TextBox();
lataTextBox = new L3TextBox();
Controls.Add(form);
if (!Page.IsPostBack)
79
{
Populate();
}
}
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;
}
}
80
Source File Code 7.2: RateCenterSearchCriteriaControl.cs
using System.Collections;
using System.Web.UI.WebControls;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web;
using Level3.Cornerstone.Web.WebControls;
/// <summary>
/// Summary description for RateCenterSearchCriteriaControl
/// </summary>
public class RateCenterSearchCriteriaControl : SearchCriteriaControl
{
private L3ListBox stateList;
private TextBox rcAbbrevTextBox;
private TextBox lataTextBox;
private IValueMapper mapper = HelloWorld.Common.HWValueMapper.Instance;
stateList = L3ControlFactory.CreateListBox();
rcAbbrevTextBox = new L3TextBox();
lataTextBox = new L3TextBox();
Controls.Add(form);
if (!Page.IsPostBack)
{
Populate();
}
}
criteria.Add("stateabbrev",
SearchCriteriaValue.Create(stateList.SelectedValue));
criteria.Add("rcabbrev",
SearchCriteriaValue.Create(rcAbbrevTextBox.Text));
criteria.Add("lata", SearchCriteriaValue.Create(lataTextBox.Text));
return criteria;
}
set
{
WebUtil.SelectItemsByValue(stateList, value["stateabbrev"].Value as
string);
rcAbbrevTextBox.Text = (string)value["rcabbrev"].Value;
81
lataTextBox.Text = (string)value["lata"].Value;
}
}
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;
}
return rateCenterResults;
}
84
Source File Code 7.3: RateCenterSearchController.cs
using System;
using HelloWorld.Services.WebServices.TAI.Maint;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web.WebControls;
namespace HelloWorld.Web.Controllers
{
public class RateCenterSearchController : SearchController
{
private WebServiceController controller;
public RateCenterSearchController()
: this(new WebServiceController())
{}
RateCenterVO[] rateCenterResponses =
controller.GetRateCentersByExample(example);
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;
86
Source File Code 7.4: WebService3.aspx.cs
using System;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;
/// <summary>
/// Summary description for WebService3
/// Cornerstone Enabled Web Form
/// </summary>
public partial class WebService3 : HWPageBase
{
#region Attributes
private SearchCriteriaControl criteriaControl;
private GridViewDefinition gridDefinition;
private SearchController searchController;
#endregion
if (!Page.IsPostBack)
{
}
}
#endregion
}
87
Module 8: Consuming Data from a Database
Module Goal:
In this module we build a search page using the same technique as the last module except the data will come
directly from a database instead of from a web service. The database we query is the Unified Auditing database
which is used to track web service calls from one IT system to another.
88
Procedure 8.1: Adding a datasource and creating the DAO
1. Open web.config and add the following element to the <connectionStrings> element:
<add name="INFSENV1" connectionString="Data Source=INFSENV1;User ID=aud_user; Password=aud_user;
pooling=true;" providerName="System.Data.OracleClient"/>
public SearchResult Search(SearchCriteria searchCriteria, string table, IValueMapper mapper, bool createIds)
{
SearchResult result = new SearchResult();
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";
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
#endregion
#region Constructors
public UnifiedAuditingSearchController()
{
dao = new UnifiedAuditingDao();
}
#endregion
return FormatXmlFields(results);
}
if (dataSet.Tables.Count > 0)
{
DataTable dataTable = dataSet.Tables[0];
return result;
}
}
}
3. Add the following GridView definition to HWGridDefinitions.xml in the HelloWorld web site:
<Grid name="unifiedauditinggriddef" dataSourceType="Database" showFooter="true" >
<Columns>
<Column dataFieldKey="auditserviceid" />
<Column dataFieldKey="correlationid" />
<Column dataFieldKey="audittimestamp" />
<Column dataFieldKey="sourceapplication" />
<Column dataFieldKey="operationname" />
<Column dataFieldKey="requestdata" characterLength="30" />
<Column dataFieldKey="responsedata" characterLength="30" />
<Column dataFieldKey="errorcode" />
<Column dataFieldKey="errormessage" characterLength="20"/>
</Columns>
</Grid>
4. Add the class “UnifiedAuditingSearchCriteriaControl” to the HelloWorld web site under the App_Code
WebControlsCriteriaControls folder and add/change its code to:
using System.Web.UI.WebControls;
using HelloWorld.Common;
using Level3.Cornerstone.Common;
using Level3.Cornerstone.Common.ValueMapper;
using Level3.Cornerstone.Data;
using Level3.Cornerstone.Web;
using Level3.Cornerstone.Web.WebControls;
/// <summary>
/// Summary description for UnifiedAuditingSearchCriteriaControl
/// </summary>
public class UnifiedAuditingSearchCriteriaControl : SearchCriteriaControl
{
private TextBox auditServiceIdTextBox;
private DateRangeControl auditTimestampDateRange;
private ListBox sourceApplicationListBox;
private TextBox operationNameTextBox;
private TextBox requestDataTextBox;
private TextBox responseDataTextBox;
93
private TextBox classNameTextBox;
private TextBox correlationIdTextBox;
private TextBox errorCodeTextBox;
private TextBox errorMessageTextBox;
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();
leftForm.AddRow(mapper.GetLabelValue("correlationid"), correlationIdTextBox);
leftForm.AddRow(mapper.GetLabelValue("sourceapplication"), sourceApplicationListBox);
leftForm.AddRow(mapper.GetLabelValue("audittimestamp"), auditTimestampDateRange);
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
return criteria;
}
set
{
EnsureChildControls();
6. The following elements inside the <Values> element of HWValueMapper.xml (note: the dtoValue
attribute is not used during this module but may be used in later modules):
<!-- DTO -->
<ValueItem key="auditserviceid" dtoValue="AuditServiceId" dbValue="AUDIT_SERVICE_ID"
presentationValue="Audit Service ID" />
<ValueItem key="audittimestamp" dtoValue="AuditTimestamp" dbValue="AUDIT_TIMESTAMP"
presentationValue="Audit Timestamp" />
<ValueItem key="sourceapplication" dtoValue="SourceApplication" dbValue="SOURCE_APPLICATION"
presentationValue="Source Application" />
95
<ValueItem key="operationName" dtoValue="OperationName" dbValue="OPERATION_NAME"
presentationValue="Operation Name" />
<ValueItem key="requestdata" dtoValue="RequestData" dbValue="REQUEST_DATA"
presentationValue="Request Data" />
<ValueItem key="responsedata" dtoValue="ResponseData" dbValue="RESPONSE_DATA"
presentationValue="Response Data" />
<ValueItem key="classname" dtoValue="ClassName" dbValue="CLASS_NAME" presentationValue="Class
Name" />
<ValueItem key="correlationid" dtoValue="CorrelationId" dbValue="CORRELATION_ID"
presentationValue="Correlation ID" />
<ValueItem key="errorcode" dtoValue="ErrorCode" dbValue="ERROR_CODE" presentationValue="Error Code"
/>
<ValueItem key="errormessage" dtoValue="ErrorMessage" dbValue="ERROR_MESSAGE"
presentationValue="Error Message" />
7. Create a new Cornerstone web page called “DataAccess1.aspx” in the HelloWorld web site and
add/change the code in the code-behind to:
using System;
using HelloWorld.Common;
using HelloWorld.Web.Controllers;
using Level3.Cornerstone.Web.WebControls;
using Level3.Cornerstone.Web.WebControls.Validation;
EnsureChildControls();
ValidationManager.AddInfo("Database search example using grid view and the search control.");
}
Controls.Add(searchControl);
}
}
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
97