MiniBank - S.A.B.I.A.

Anuncio
Marcos de Desarrollo
Diseño e implementación de aplicaciones Web con .NET
Contenido
 En este apartado estudiaremos el diseño e implementación de las capas controlador y vista de MiniBank
 Configuración de la aplicación Web
 Página maestra de MiniBank
 Un ejemplo de una acción que realiza una operación que no visualiza resultados 
Transferencia bancaria
 Un ejemplo de una acción que realiza una operación y visualiza el resultado de la operación 
Búsqueda de cuentas bancarias por identificador de cuenta (resultado en una página) o de usuario (resultado en varias páginas)
 Internacionalización
Introducción
Configuración: Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<!‐‐ Cultural preferences of the Web site ‐‐>
<globalization culture="auto" uiCulture="auto" />
<!‐‐ Valid Options: UseUri (True), UseCookies (False), AutoDetect ‐‐>
<sessionState cookieless="AutoDetect" timeout="30" />
<!‐‐ Valid Options: On, Off, RemoteOnly ‐‐>
<customErrors mode="RemoteOnly" defaultRedirect="/Errors/InternalError.aspx">
</customErrors>
<<...>>
</system.web>
<!‐‐ Unity configuration block ‐‐>
<unity>
<!‐‐ Identico a App.config en MiniBank (model) ‐‐>
</unity>
Configuración: Web.config
<applicationSettings>
<Es.Udc.DotNet.MiniBank.Web.Properties.Settings>
<setting name="MiniBank_defaultCount" serializeAs="String">
<value>2</value>
</setting>
...
</Es.Udc.DotNet.MiniBank.Web.Properties.Settings>
</applicationSettings>
No confundir con appSettings
No actualizar esta sección directamente
sobre Web.config, sino desde la pestaña
de configuración del proyecto =>
actualiza Settings.settings y
Settings.designer.cs
Configuración: Web.config
 Pestaña Settings en las propiedades del proyecto
Permite acceso "tipado".
P. ej.: Settings.Default.MiniBank_defaultCount;
Configuración: Global.asax
namespace Es.Udc.DotNet.MiniBank.Web
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Application.Lock();
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section =
(UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(container);
Application["UnityContainer"] = container;
Application.UnLock();
}
<<...>>
Configuración: otras opciones
Contenido
 En este apartado estudiaremos el diseño e implementación de las capas controlador y vista de MiniBank
 Configuración de la aplicación Web
 Página maestra de MiniBank
 Un ejemplo de una acción que realiza una operación que no visualiza resultados 
Transferencia bancaria
 Un ejemplo de una acción que realiza una operación y visualiza el resultado de la operación 
Búsqueda de cuentas bancarias por:
 identificador de cuenta (resultado en una página)
 identificador de usuario (resultado en varias páginas)
 Internacionalización
MiniBank.Master: Vista de diseño
MiniBank.Master: Vista de código
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MiniBank.master.cs"
Inherits="Es.Udc.DotNet.MiniBank.Web.MiniBank" %>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1‐transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>MiniBank</title>
<meta http‐equiv="Content‐Type" content="text/html; charset=iso‐8859‐1"/>
<link href="~/Img/MiniBank.ico" rel="Shortcut Icon" />
<link href="~/Css/MiniBank.Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="window">
<!‐‐ Body Header. ‐‐>
<div id="header">
<asp:Localize ID="lclHeader" runat="server" meta:resourcekey="lclHeader" />
</div>
MiniBank.Master: Vista de código
<!‐‐ Main Content. ‐‐>
<div id="pageBody">
<div id="sidebar">
<ul>
<li>
<asp:HyperLink ID="lnkHome" runat="server" meta:resourcekey="lnkHome"
NavigateUrl="~/Pages/MainPage.aspx" />
</li>
<!‐‐ Mas HyperLinks... ‐‐>
</ul>
</div>
<div id="content">
<asp:ContentPlaceHolder ID="ContentPlaceHolderMain" runat="server">
</asp:ContentPlaceHolder>
</div>
</div>
<!‐‐ Footer. ‐‐>
<div id="footer">
<asp:Localize ID="lclFooter" runat="server" meta:resourcekey="lclFooter" />
</div>
</div>
</body>
</html>
MiniBank.Master.cs
using System;
namespace Es.Udc.DotNet.MiniBank.Web
{
public partial class MiniBank : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
MiniBank.Master.designer.cs
namespace Es.Udc.DotNet.MiniBank.Web {
public partial class MiniBank {
protected global::System.Web.UI.WebControls.Localize lclHeader;
protected global::System.Web.UI.WebControls.HyperLink lnkHome;
protected global::System.Web.UI.WebControls.HyperLink lnkCreate;
<<...>>
protected global::System.Web.UI.WebControls.ContentPlaceHolder
ContentPlaceHolderMain;
protected global::System.Web.UI.WebControls.Localize lclFooter;
}
}
Contenido
 En este apartado estudiaremos el diseño e implementación de las capas controlador y vista de MiniBank
 Configuración de la aplicación Web
 Página maestra de MiniBank
 Un ejemplo de una acción que realiza una operación que no visualiza resultados 
Transferencia bancaria
 Un ejemplo de una acción que realiza una operación y visualiza el resultado de la operación 
Búsqueda de cuentas bancarias por:
 identificador de cuenta (resultado en una página)
 identificador de usuario (resultado en varias páginas)
 Internacionalización
Transferencia
Transfer.aspx
SuccessfulOperation.aspx
Transferencia: Transfer.aspx (Vista de diseño)
Transferencia: Transfer.aspx.designer.cs
namespace Es.Udc.DotNet.MiniBank.Web.Pages {
public partial class Transfer {
protected global::System.Web.UI.HtmlControls.HtmlForm TransferForm;
protected global::System.Web.UI.WebControls.Localize lclSourceAccId;
protected global::System.Web.UI.WebControls.Localize lclDestinationAccId;
protected global::System.Web.UI.WebControls.Localize lclAmount;
protected global::System.Web.UI.WebControls.TextBox txtSourceAccId;
protected global::System.Web.UI.WebControls.TextBox txtDestinationAccId;
protected global::System.Web.UI.WebControls.TextBox txtAmount;
protected global::System.Web.UI.WebControls.Label lblSourceAccError;
protected global::System.Web.UI.WebControls.Label lblDestinationAccError;
protected global::System.Web.UI.WebControls.Label lblAmountError;
Transferencia: Transfer.aspx.designer.cs
protected global::System.Web.UI.WebControls.RequiredFieldValidator
rfvSourceAccId;
protected global::System.Web.UI.WebControls.RequiredFieldValidator
rfvDestinationAccId;
protected global::System.Web.UI.WebControls.RequiredFieldValidator
rfvBalance;
protected global::System.Web.UI.WebControls.RegularExpressionValidator
typeSourceAccIdValidator;
protected global::System.Web.UI.WebControls.RegularExpressionValidator
typeDestinationAccId;
protected global::System.Web.UI.WebControls.RegularExpressionValidator
typeAmountValidator;
protected global::System.Web.UI.WebControls.Button btnTransfer;
}
}
Transferencia: Transfer.aspx (Vista de código)
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Transfer.aspx.cs"
Inherits="Es.Udc.DotNet.MiniBank.Web.Pages.Transfer" MasterPageFile="~/MiniBank.Master" %>
<asp:Content ID="content" ContentPlaceHolderID="ContentPlaceHolderMain" runat="server">
<div id="form">
<form id="TransferForm" method="post" runat="server">
<div class="field">
<span class="label">
<asp:Localize ID="lclSourceAccId" runat="server"
Localización explícita. Acceso a archivo
meta:resourcekey="lclSourceAccId" /></span>
de recursos global llamado "Common"
(Common.resx, Common.es-ES.resx, …).
<span class="entry">
<asp:TextBox ID="txtSourceAccId" runat="server" Width="200px"
Mensaje: "Invalid data type"
Columns="16"></asp:TextBox>
<asp:RegularExpressionValidator ID="typeSourceAccIdValidator" runat="server"
ControlToValidate="txtSourceAccId" Text="<%$ Resources: Common, typeError %>" ValidationExpression="(\d)*" CssClass="errorMessage" Display="Dynamic">
</asp:RegularExpressionValidator>
Transferencia: Transfer.aspx (Vista de código)
<asp:RequiredFieldValidator ID="rfvSourceAccId" runat="server"
ControlToValidate="txtSourceAccId" Display="Dynamic"
Text="<%$ Resources: Common, mandatoryField %>" CssClass="errorMessage">
</asp:RequiredFieldValidator>
<asp:Label ID="lblSourceAccError" runat="server" CssClass="errorMessage"
meta:resourcekey="lblSourceAccError">
</asp:Label>
Localización implícita. Acceso a archivo
</span>
de recursos local asociado a
</div>
Transfer.aspx
(Transfer.resx, Transfer.es-Es.resx, …)
<<...>>
Mensaje: "Source Account not Found"
<div class="button">
<asp:Button ID="btnTransfer" runat="server" meta:resourcekey="btnTransfer"
OnClick="BtnTransfer_Click" />
</div>
</form>
Indica el nombre del método que tratará
</div>
el evento OnClick
</asp:Content>
Transferencia: Transfer.aspx.cs
public partial class Transfer : SpecificCulturePage
{
protected void Page_Load(object sender, EventArgs e)
{
lblSourceAccError.Visible = false;
lblDestinationAccError.Visible = false;
lblAmountError.Visible = false;
}
protected void BtnTransfer_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
/* Get data. */
long sourceAccountIdentifier = Convert.ToInt32(txtSourceAccId.Text);
long destinationAccountIdentifier = Convert.ToInt32(txtDestinationAccId.Text);
double amount = Convert.ToInt64(txtAmount.Text);
Transferencia: Transfer.aspx.cs
/* Transfer. */
try
{
/* Get the Service */
IUnityContainer container = (IUnityContainer)Application["unityContainer"];
IAccountService accountService = container.Resolve<IAccountService>();
accountService.Transfer(sourceAccountIdentifier, destinationAccountIdentifier, amount);
Response.Redirect(Response.
ApplyAppPathModifier("./SuccessfulOperation.aspx"));
}
Transferencia: Transfer.aspx.cs
catch (InstanceNotFoundException ex)
{
long key = (long)ex.Key;
/* Process errors and show labels */
if (key.Equals(sourceAccountIdentifier))
lblSourceAccError.Visible = true;
else
lblDestinationAccError.Visible = true;
}
catch (InsufficientBalanceException ex)
{
/* lblAmmountError.Text is something like "Insufficient balance * in source account (balance = {0})" */
String labelText = String.Format(
(string)GetLocalResourceObject("lblAmountError.Text"),
ex.CurrentBalance);
lblAmountError.Text = labelText;
lblAmountError.Visible = true;
}
} // if
} // BtnTransferClick
} // Transfer Class
Queremos que se muestre el saldo
como parte del mensaje, con soporte
para internacionalización
Contenido
 En este apartado estudiaremos el diseño e implementación de las capas controlador y vista de MiniBank
 Configuración de la aplicación Web
 Página maestra de MiniBank
 Un ejemplo de una acción que realiza una operación que no visualiza resultados 
Transferencia bancaria
 Un ejemplo de una acción que realiza una operación y visualiza el resultado de la operación 
Búsqueda de cuentas bancarias por:
 identificador de cuenta (resultado en una página)
 identificador de usuario (resultado en varias páginas)
 Internacionalización
Búsqueda de cuentas por identificador de cuenta
FindAccounts.aspx
ShowAccountByAccID.aspx
Búsqueda de cuentas por identificador de usuario
FindAccounts.aspx
ShowAccountsByUserID.aspx
Búsqueda de cuentas: FindAccounts.aspx (Vista de diseño)
Búsqueda de cuentas: FindAccounts.aspx (Vista de código)
<asp:Content ID="content1" ContentPlaceHolderID="ContentPlaceHolderMain"
runat="server">
<div id="form">
<form id="FindForm" method="post" runat="server">
<div class="field">
<span class="label">
<asp:Localize ID="lclIdentifier" runat="server"
meta:resourcekey="lblIdentifier" />
</span>
<span class="entry">
<asp:TextBox ID="txtIdentifier" runat="server" Width="200px"
Columns="16" />
<asp:RegularExpressionValidator ID="typeValidator" runat="server"
ControlToValidate="txtIdentifier" ValidationExpression="(\d)*"
Text="<%$ Resources: Common, typeError %>" Display="Dynamic"
CssClass="errorMessage" />
<asp:RequiredFieldValidator ID="rfvIdentifier" runat="server"
ControlToValidate="txtIdentifier" Display="Dynamic"
Text="<%$ Resources: Common, mandatoryField %>"
CssClass="errorMessage" />
<asp:Label CssClass="errorMessage" ID="lblIdentifierError"
runat="server" meta:resourcekey="lblIdentifierError" />
</span>
</div>
Búsqueda de cuentas: FindAccounts.aspx (Vista de código)
<div class="field">
<span class="label">
<asp:Localize ID="lclFindBy" runat="server"
meta:resourcekey="lclFindBy" />
</span>
<span class="entry">
<asp:DropDownList ID="ddlFindBy" runat="server" Width="200px">
<asp:ListItem Value="accID"
Text="<%$ Resources:Common, accId %>" />
<asp:ListItem Value="userID"
Text="<%$ Resources:Common, userId %>" />
</asp:DropDownList>
</span>
</div>
<div class="button">
<asp:Button ID="btnFind" runat="server" meta:resourcekey="btnFind"
OnClick="BtnFind_Click" />
</div>
</form>
</div>
</asp:Content>
Búsqueda de cuentas: FindAccounts.aspx.cs
public partial class FindAccounts : SpecificCulturePage
{
protected void Page_Load(object sender, EventArgs e)
{
lblIdentifierError.Visible = false;
}
Búsqueda de cuentas: FindAccounts.aspx.cs
protected void BtnFind_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
/* Get data. */
String identifierType = this.ddlFindBy.SelectedValue;
Int32 identifier = Convert.ToInt32(this.txtIdentifier.Text);
/* Do action. */
if (identifierType == "accID")
{
FindAccountByAccountIdentifier(identifier);
}
else
{
String url = String.Format("./ShowAccountsByUserID.aspx?userID={0}", identifier);
Response.Redirect(Response.ApplyAppPathModifier(url));
}
}
Búsqueda de cuentas: FindAccounts.aspx.cs
private void FindAccountByAccountIdentifier(long accountIdentifier)
{
try
{
/* Get the Service */
/* Get Account Data */
Account account = accountService.FindAccount(accountIdentifier);
/* Attach data to context */
Context.Items.Add("account", account);
/* Transfer to visualization WebForm */
Server.Transfer(Response.
ApplyAppPathModifier("./ShowAccountByAccID.aspx"));
}
catch (InstanceNotFoundException)
{
lblIdentifierError.Visible = true;
}
}
}
Búsqueda de cuentas: FindAccounts.aspx.cs
private void FindAccountByAccountIdentifier(long accountIdentifier)
{
try
{
/* Get the Service */
/* Get Account Data */
Account account = accountService.FindAccount(accountIdentifier);
/* Attach data to context */
Context.Items.Add("account", account);
Permite almacenar datos que se
necesitarán más adelante, durante el
mismo postback
/* Transfer to visualization WebForm */
Server.Transfer(Response.
ApplyAppPathModifier("./ShowAccountByAccID.aspx"));
}
catch (InstanceNotFoundException)
{
lblIdentifierError.Visible = true;
}
}
}
Búsqueda de cuentas por identificador de cuenta
FindAccounts.aspx
ShowAccountByAccID.aspx
Búsqueda de cuentas: ShowAccountByAccID.aspx (Vista de diseño)
Búsqueda de cuentas: ShowAccountByAccID.aspx (Vista de código)
<asp:Content ID="content1" ContentPlaceHolderID="ContentPlaceHolderMain" runat="server">
<asp:Table CssClass="accountDetails" ID="TableAccountInfo" runat="server">
<asp:TableRow runat="server">
<asp:TableHeaderCell ID="cellCaptionAccountID" runat="server"
Text="<%$ Resources:Common, accId %>"></asp:TableHeaderCell>
<asp:TableCell ID="cellAccountID" runat="server"></asp:TableCell>
</asp:TableRow>
<asp:TableRow runat="server">
<asp:TableHeaderCell ID="cellCaptionUserID" runat="server"
Text="<%$ Resources:Common, userId %>"></asp:TableHeaderCell>
<asp:TableCell ID="cellUserID" runat="server"></asp:TableCell>
</asp:TableRow>
<asp:TableRow runat="server">
<asp:TableHeaderCell ID="cellCaptionBalance" runat="server"
Text="<%$ Resources:Common, balance %>"></asp:TableHeaderCell>
<asp:TableCell ID="cellBalance" runat="server"></asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:Content>
Búsqueda de cuentas: ShowAccountByAccID.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
Account account = (Account)Context.Items["account"];
cellAccountID.Text = account.accId.ToString();
cellUserID.Text = account.usrId.ToString();
cellBalance.Text = account.balance.ToString();
}
Búsqueda de cuentas por identificador de usuario
FindAccounts.aspx
ShowAccountsByUserID.aspx
Búsqueda de cuentas: ShowAccountsByUserID.aspx (Vista de diseño)
GridView
 Tipos de columnas
 BoundField, CheckBox, ButtonField, HyperLinkField, etc.
 No es obligatorio indicar las columnas, pueden autogenerarse
 AutoGenerateColumns=True muestra todo el contenido del origen de datos
 Code‐Behind:
gvXXX.DataSource = <<...>>;
gvXXX.DataBind();
// Origen de Datos: DataTable, ArrayList, ...
GridView
 Ofrece la posibilidad de realizar la paginación de los resultados
 Propiedades
 AllowPaging: habilita la paginación
 PageIndex: índice de la página a mostrar (zero‐based)
 PageSize: número de registros por página
 … pero recupera la totalidad de los datos y posteriormente los pagina
 Ideal: recuperar únicamente los datos que serán mostrados
GridView
 Opciones:
 Opción 1: Separar representación visual de comportamiento

Se ilustra en ShowAccountsByUserID
 Opción 2: ObjectDataSource
 Se ilustra en ShowAccOperations
GridView
 Opción 1: Separar representación visual de comportamiento
 Datos se recuperan a partir de un caso de uso que soporta paginación
/* Get Accounts Info */
List<Account> accounts = accountService.FindAccountsByUserIdentifier(userID, startIndex, count);
 GridView visualiza los datos
 Estableciendo el DataSource adecuado y realizando el DataBind
 Paginación se delega en sendos linkButtons para avanzar y retroceder página
Búsqueda de cuentas: ShowAccountsByUserID.aspx (Vista de código)
<asp:Content ID="content1" ContentPlaceHolderID="ContentPlaceHolderMain"
runat="server">
<form runat="server">
<p>
<asp:Label ID="lblNoUserAccounts" meta:resourcekey="lblNoUserAccounts"
runat="server">
</asp:Label>
</p>
<asp:GridView ID="gvUserAccounts" runat="server" CssClass="userAccounts"
GridLines="None" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="accId"
HeaderText="<%$ Resources:Common, accId %>" />
<asp:BoundField DataField="balance"
HeaderText="<%$ Resources:Common, balance %>" />
</Columns>
</asp:GridView>
</form>
Búsqueda de cuentas: ShowAccountsByUserID.aspx (Vista de código)
<!‐‐ "Previous" and "Next" links. ‐‐>
<div class="previousNextLinks">
<span class="previousLink">
<asp:HyperLink ID="lnkPrevious" Text="<%$ Resources:Common, Previous %>"
runat="server" Visible="False">
</asp:HyperLink>
</span>
<span class="nextLink">
<asp:HyperLink ID="lnkNext" Text="<%$ Resources:Common, Next %>"
runat="server" Visible="False">
</asp:HyperLink>
</span>
</div>
</asp:Content>
Los enlaces next y previous son controles asp:HyperLink, que pueden gestionarse
fácilmente desde CB, controlando si deben mostrarse o no, así como la ruta a la que
apuntan.
Búsqueda de cuentas: ShowAccountsByUserID.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
int startIndex, count;
lnkPrevious.Visible = false;
lnkNext.Visible = false;
lblNoUserAccounts.Visible = false;
/* Get User Identifier passed as parameter in the request from * the previous page */
long userID = Convert.ToInt32(Request.Params.Get("userID"));
/* Get Start Index */
try
{
startIndex = Int32.Parse(Request.Params.Get("startIndex"));
}
catch (ArgumentNullException)
{
startIndex = 0;
}
Búsqueda de cuentas: ShowAccountsByUserID.aspx.cs
/* Get Count */
try
{
count = Int32.Parse(Request.Params.Get("count"));
}
catch (ArgumentNullException)
{
count = Settings.Default.MiniBank_defaultCount;
}
/* Get the Service */
IUnityContainer container = ...
/* Get Accounts Info */
List<Account> accounts = accountService.FindAccountsByUserIdentifier(userID, startIndex, count);
if (accounts.Count == 0)
{
lblNoUserAccounts.Visible = true;
return;
}
Búsqueda de cuentas: ShowAccountsByUserID.aspx.cs
this.gvUserAccounts.DataSource = accounts;
this.gvUserAccounts.DataBind();
/* Get the number of accounts in order to manage the previous * and next links */
int numberOfAccounts = accountService.GetNumberOfAccounts(userID);
/* "Previous" link */
if ((startIndex ‐ count) >= 0)
{
String url = Settings.Default.MiniBank_applicationURL +
"/ShowAccountsByUserID.aspx" + "?userID=" + userID +
"&startIndex=" + (startIndex ‐ count) + "&count=" + count;
this.lnkPrevious.NavigateUrl = Response.ApplyAppPathModifier(url);
this.lnkPrevious.Visible = true;
}
Búsqueda de cuentas: ShowAccountsByUserID.aspx.cs
/* "Next" link */
if ((startIndex + count) < numberOfAccounts)
{
String url = Settings.Default.MiniBank_applicationURL +
"/ShowAccountsByUserID.aspx" + "?userID=" + userID +
"&startIndex=" + (startIndex + count) + "&count=" + count;
this.lnkNext.NavigateUrl = Response.ApplyAppPathModifier(url);
this.lnkNext.Visible = true;
}
}
GridView
 Opciones:
 Opción 1: Separar representación visual de comportamiento

Se ilustra en ShowAccountsByUserID
 Opción 2: ObjectDataSource
 Se ilustra en ShowAccOperations
Búsqueda de operaciones bancarias
FindAccountOperations.aspx
ShowAccOperations.aspx
GridView
 Opción 2: ObjectDataSource
 Componente que permite recuperar objetos bajo demanda de un repositorio y enlazarlos como un origen de datos
ObjectDataSource
 Propiedades relacionadas con la paginación

EnablePaging

TypeName: indica el tipo de dato que define los métodos empleados para realizar la paginación
 e.g.: Es.Udc.DotNet.MiniBank.Model.AccountService.AccountService

SelectMethod: nombre del método que realiza la búsqueda mediante Page‐by‐Page
 e.g.: FindAccountOperationsByDate

Los parámetros específicos se indican mediante la colección SelectParameters
.SelectParameters.Add("accountIdentifier", DbType.Int64,
accID.ToString());
.SelectParameters.Add("startDate", DbType.DateTime,
startDate.ToString());
.SelectParameters.Add("endDate", DbType.DateTime,
endDate.ToString());
ObjectDataSource
 Propiedades relacionadas con la paginación (cont.)

SelectCountMethod: nombre del método que devuelve el número máximo de registros
 e.g.: GetNumberofAccountOperations

StartRowIndexParameterName: nombre del parámetro que indica el registro a partir del cual se búsqueda  e.g.: startIndex

MaximumRowsParameterName: Nombre del parámetro que indica el número de registros recuperados por consulta
 e.g.: count
ObjectDataSource
 Funcionamiento
 Se crea automáticamente una instancia del tipo declarado en DataSource.TypeName
 pbpDataSource.TypeName = "Es.Udc.DotNet.MiniBank.Model.AccountService.AccountService"; implica una llamada a new AccountService();
 Problema: en MiniBank la instanciación de AccountService implica resolución de dependencias, que de esta forma no se realizarán
 Solución:

Capturar el evento ObjectCreating y realizar las operaciones necesarias para que se resuelvan las dependencias
ObjectDataSource
 Funcionamiento
 En Page_Load se declara el delegado
pbpDataSource.ObjectCreating += this.pbpDataSource_ObjectCreating;
 Luego se implementa el delegado
protected void pbpDataSource_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
// Aqui se instancia el objeto DataSource.TypeName
// Por defecto: new DataSourceTypeName. Por ej: new AccountService()
// pero se puede dar implementacion alternativa
}
ObjectDataSource
 pbpDataSource_ObjectCreating
protected void pbpDataSource_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
/* Get the Service */
IUnityContainer container = (IUnityContainer)
HttpContext.Current.Application["unityContainer"];
IAccountService accountService = new AccountService();
accountService = (IAccountService)
container.BuildUp(accountService.GetType(), accountService);
e.ObjectInstance = accountService;
}
Hace que se carguen las
dependencias de
AccountService.
container.Resolve<IAccountService>();
No funciona.
Búsqueda de operaciones bancarias: ShowAccOperations.aspx (Vista de código)
<asp:Content ID="content" ContentPlaceHolderID="ContentPlaceHolderMain" runat="server">
<p>
<asp:Label ID="lblInvalidAccount" meta:resourcekey="lblInvalidAccount" runat="server" Visible=false></asp:Label>
</p>
<form runat="server">
<asp:GridView ID="gvAccOperations" runat="server" CssClass="accountOperations" AutoGenerateColumns="False" onpageindexchanging="gvAccOperations_PageIndexChanging" ShowHeaderWhenEmpty="True">
<Columns>
<asp:BoundField DataField="Date" HeaderText="<%$ Resources:, date %>" />
<asp:BoundField DataField="Type" HeaderText="<%$ Resources:, type %>" />
<asp:BoundField DataField="Amount" HeaderText="<%$ Resources:, amount %>" />
</Columns>
</asp:GridView>
<br />
</form>
Búsqueda de operaciones bancarias: ShowAccOperations.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
try
{
pbpDataSource.ObjectCreating += this.pbpDataSource_ObjectCreating;
pbpDataSource.TypeName = "Es.Udc.DotNet.MiniBank.Model.AccountService.AccountService";
pbpDataSource.EnablePaging = true;
pbpDataSource.SelectMethod = "FindAccountOperationsByDate";
/* Get Account Identifier */
long accID = Convert.ToInt32(Request.Params.Get("accID"));
/* Get the start and end date (without time) */
DateTime startDate = Convert.ToDateTime(Request.Params.Get("startDate"));
DateTime endDate
//... Búsqueda de operaciones bancarias: ShowAccOperations.aspx.cs (cont)
pbpDataSource.SelectParameters.
Add("accountIdentifier", DbType.Int64, accID.ToString());
pbpDataSource.SelectParameters.
Add("startDate", DbType.DateTime, startDate.ToString());
pbpDataSource.SelectParameters.
Add("endDate", DbType.DateTime, endDate.ToString());
pbpDataSource.SelectCountMethod = "GetNumberofAccountOperations";
pbpDataSource.StartRowIndexParameterName = "startIndex";
pbpDataSource.MaximumRowsParameterName = "count";
gvAccOperations.AllowPaging = true;
int count = Settings.Default.MiniBank_defaultCount;
gvAccOperations.PageSize = count;
gvAccOperations.DataSource = pbpDataSource;
gvAccOperations.DataBind();
}
catch (Exception)
{
lblInvalidAccount.Visible = true;
}
}
Búsqueda de operaciones bancarias: ShowAccOperations.aspx.cs (cont)
protected void gvAccOperations_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvAccOperations.PageIndex = e.NewPageIndex;
gvAccOperations.DataBind();
}
protected void pbpDataSource_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
/* Get the Service */
IUnityContainer container = (IUnityContainer)HttpContext.Current.Application["unityContainer"]; IAccountService accountService = new AccountService();
accountService = (IAccountService)container.BuildUp(accountService.GetType(), accountService);
e.ObjectInstance = accountService;
}
Contenido
 En este apartado estudiaremos el diseño e implementación de las capas controlador y vista de MiniBank
 Configuración de la aplicación Web
 Página maestra de MiniBank
 Un ejemplo de una acción que realiza una operación que no visualiza resultados 
Transferencia bancaria
 Un ejemplo de una acción que realiza una operación y visualiza el resultado de la operación 
Búsqueda de cuentas bancarias por identificador de cuenta (resultado en una página) o de usuario (resultado en varias páginas)
 Internacionalización
Selección de idioma y país Cuando cambia el idioma,
se actualiza la lista de países
y se muestran en el idioma
seleccionado, ordenados
alfabéticamente
SetLocale.aspx
Selección de idioma y país: SetLocale.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
String language;
String country;
if (!IsPostBack)
{
/* * We check if exists a locale in the session. In this case, * we get the language and the region/country from the locale.
* Other case we use the browser preferences to extract the
* language and the region/country
*/
if (!SessionManager.IsLocaleDefined(Context))
{
/* Gets preferred language from browser */
language = GetLanguageFromBrowserPreferences();
country = GetCountryFromBrowserPreferences();
}
Selección de idioma y país: SetLocale.aspx.cs
else
{
Locale locale = SessionManager.GetLocale(Context);
language = locale.Language;
country = locale.Country;
}
/* Finally we update de data of the "Combo", using the
* selected language and region/country.
*/
UpdateComboLanguage(language);
UpdateComboCountry(language, country);
}
}
Selección de idioma y país: SetLocale.aspx.cs
private String GetLanguageFromBrowserPreferences()
{
String language;
CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
language = cultureInfo.TwoLetterISOLanguageName;
return language;
}
Selección de idioma y país: SetLocale.aspx.cs
private String GetCountryFromBrowserPreferences()
{
String country;
CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
if (cultureInfo.IsNeutralCulture)
{
country = "";
}
else
{
// cultureInfoName is something like en‐US
String cultureInfoName = cultureInfo.Name;
// Gets the last two caracters of cultureInfoname
country = cultureInfoName.Substring(cultureInfoName.Length ‐ 2);
}
return country;
}
Selección de idioma y país: SetLocale.aspx.cs
private void UpdateComboLanguage(String selectedLanguage)
{
this.comboLanguage.DataSource = Languages.GetLanguages(selectedLanguage);
this.comboLanguage.DataTextField = "value";
this.comboLanguage.DataValueField = "text";
this.comboLanguage.DataBind();
this.comboLanguage.SelectedValue = selectedLanguage;
}
private void UpdateComboCountry(String selectedLanguage, String selectedCountry)
{
this.comboCountry.DataSource = Countries.GetCountries(selectedLanguage);
this.comboCountry.DataTextField = "value";
this.comboCountry.DataValueField = "text";
this.comboCountry.DataBind();
this.comboCountry.SelectedValue = selectedCountry;
}
Selección de idioma y país: SetLocale.aspx.cs
protected void BtnSetLocale_Click(object sender, EventArgs e)
{
string language = comboLanguage.SelectedValue;
string country = comboCountry.SelectedValue;
Locale locale = new Locale(language, country);
SessionManager.SetLocale(Context, locale);
Response.Redirect(Response.
ApplyAppPathModifier("~/MainPage.aspx"));
}
Selección de idioma y país: SetLocale.aspx.cs
<asp:DropDownList ID="comboLanguage" runat="server" AutoPostBack="True"
Width="100px" OnSelectedIndexChanged="ComboLanguageSelectedIndexChanged">
</asp:DropDownList>
SetLocale.aspx
protected void ComboLanguage_SelectedIndexChanged(object sender, EventArgs e)
{
/* After a language change, the countries are printed in the
* correct language.
*/
this.UpdateComboCountry(comboLanguage.SelectedValue, comboCountry.SelectedValue);
}
SetLocale.aspx.cs
NOTA: prueba a cambiar AutoPostBack="False". ¿Qué ocurre?
SpecificCulturePage
 Extiende a System.Web.UI.Page y todas las páginas del sitio deben extenderla
protected override void InitializeCulture()
{
if (SessionManager.IsLocaleDefined(Context))
{
Locale locale = SessionManager.GetLocale(Context);
String culture = locale.Language + "‐" + locale.Country;
CultureInfo cultureInfo;
try
{
cultureInfo = CultureInfo.CreateSpecificCulture(culture);
LogManager.RecordMessage("Specific culture created: " + cultureInfo.Name);
}
catch (ArgumentException)
{
cultureInfo = CultureInfo.CreateSpecificCulture("en‐US");
}
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
}
Descargar