Saturday, January 26, 2008

How to use Footnote to annotate a Web Page

JHA Fundperformance uses Genearic List to render foonotes for product title and each fund. In general render footnotes requires insert DataBinding Expression at the right location and keep counter updated.
Here are the code for simplest Footnoting a Web Page:

<%@ Page Language="C#" ... Inherits="TestFootNotes._Default" %>

Test Footnoting a web page<br />
Web Pages are structure less<%# RenderFootNoteNumber("struct") %> writting of information. Therefore, annotate certain part of it requires putting a structure at certain location<%# RenderFootNoteNumber("location") %>.
<hr />
Footnotes: <br />
<asp:Repeater ID="Repeater1" runat="server" DataSource="<%# _FootnoteList %>">
<ItemTemplate>
[<%# Eval("key") %>]. <%# Eval("value") %><br />
</ItemTemplate>
</asp:Repeater>



public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
public Dictionary _FootnoteList = new Dictionary();
public string RenderFootNoteNumber(string AnnotationID)
{
int i=_FootnoteList.Count;
_FootnoteList.Add(i + 1, "Footnote Content for Annotation of " + AnnotationID );
return "<sup>["+_FootnoteList.Count.ToString()+"]</sup>";
}
}


The key is to have _FootNoteList as a holder of footnote counter and content as we going through the Web Page.

Friday, January 25, 2008

MVP Design Pattern vs. MVC design Pattern

JHA FundPerformance uses MVP ( Model View Presenter) design Pattern to render Fund Performance Data. In fact, ASP.Net uses Code-Behind to convert user action/events to Request to data. But JHA FundPerformance add one more layer MTData as DataObject. Specifically, Object Data Source explicitly separate Select/Insert/Update actions from other User Events handler in ASP.Net code-behind and that is the reason we called it "DataObject Presenter".

As a general rule, MVP requires user requests hit View first and then decide which Presenter method to call. On the contrary, MVC (Model View Controller) as implemented in ASP.Net MVC framework CTP routes user requests to Controller first and then decide which View to render.

Thursday, January 24, 2008

Two way databinding in ASP.net

It is very easy to one-way databind from code behind to Markup:

<%@ Page CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<%# Name %>

namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
public string Name
{
get { return "JHA"; }
}

The other way from markup back to code-behind is a little difficult to write but Microsoft has created "Object Data Source" to make picking up data much easier:


<Form runat="server">
<asp:textbox runat="server" id="tb1">
<asp:objectdatasource runat="server" id="ods1" runat="server"
TypeName="WebApplication1._Default" SelectMethod="Test">
<SelectParameters>
<asp:ControlParameter ControlID="tb1" Name="Email" />
</SelectParameters>
</asp:objectdatasource>
<asp:Button runat="server" />
</Form>

In essence, Databinding become two-way using ObjectDataSource Select, update, Insert methods.


protected override void OnPreRender(EventArgs e)
{
DataBind();
ods1.Select();
}
public void Test(string Email) // email parameter will be filled by text from tb1
{
}

How to build NUnitASP container using HTML source

JHA site uses nested Master Page to host content, eg. PrivateBase is inside Site.Master

<%@ Master MasterPageFile="Site.Master" Inherits="ManulifeUSA.Common.Web.UI.UserControls.PrivateBase" %>

<asp:Content ContentPlaceHolderID="mainContentPlaceHolder">

<asp:PlaceHolder ID="rightPlaceHolderContainer" runat="Server">

Note that "rightPlaceHolderContainer" is nested inside "mainContentPlaceHolder" as well.

This structure will generate the following HTML sourcece in AddressChangePage.aspx as follows:

<input type="submit" id="ctl00_ctl00_mainContentPlaceHolder_rightPlaceHolder_btnUpdateAddress" />

Note that the id is the clue for constructing containers for NUnitASP testing, namely, ctl00 referes to SiteMaster, the 2nd ctl00 refers to PrivateBase, etc.
Since I have abstracted "ctl00_ctl00_mainContentPlaceHolder" into the following Test Container:

Public Class PrivateBaseTester
Inherits UserControlTester
Sub New(ByVal SiteID As String, ByVal PrivateBaseID As String, ByVal rightPlaceHolderID As String)
MyBase.New(rightPlaceHolderID, New UserControlTester("mainContentPlaceHolder",

New UserControlTester(PrivateBaseID, New UserControlTester(SiteID))))
End Sub
End Class


You would need to construct containers for btnUpdateAddress in the following manner:

Dim master As New PrivateBaseTester("ctl00", "ctl00", "rightPlaceHolder")

Dim btnUpdateAddress As New ButtonTester("btnUpdateAddress", master)

I hope this will help developers understand the approach to create container chains.

Wednesday, January 23, 2008

Use Enum in Object Data Source

JHA Performance Page uses Object Data Source to pick up Http Form Submitted data --- the so called two way data binding. For April 08 release, we need introduce Enum Type to model 3-states for Performance Type and the following class could be used to pick up Enum as input.

Public Enum PerformanceTypeEnum
Daily
Standard
AdjNonStandard
End Enum

Public Class MTData
public Function GetData(pt as PerformanceTypeEnum) as IList
End Class

<asp:ObjectDataSource id="ods1" TypeName="MTData" SelectMethod="GetData" OnSelecting="ods1_Selecting" >
<asp:SelectParameters >

<asp:Parameter Name='pt" type="String" >

Public Sub Ods1_Selectting (sender as Object, e as ObjectDataSourceEventArgs)
e.InputParameters("pt") = PerformanceTypeEnum.Daily
End Sub


Note that the parameter defined in the markup cannot have PerformanceTypeEnum as its type