ASP (Active Server Pages)

Anuncio
ASP.NET
TEMA 1: PRIMEROS PASOS
PROCESAMIENTO DINÁMICO
Internet se basa en el modelo cliente−servidor.
Modelo petición − respuesta:
Un equipo contiene información (servidor) y otro solicita la información (cliente). Es estático. No puede
proporcionar información dinámica o procesamiento. (HTML)
Un equipo contiene información (servidor) y otro solicita la información (cliente) dinámicamente. (ASP). El
servidor analiza la información antes de enviarla.
Modelo controlado por eventos:
El servidor espera a que algo ocurra en el cliente para entrar en acción y ejecutar alguna tarea. (ASP.NET)
ASP.NET sabe lo que ocurre en el cliente porque se basa en el procesamiento en el cliente para simular un
modelo controlado por eventos.
Procesamiento en el cliente
Código de programación en una página HTML que el explorador web ejecuta.
<html>
<head>
<script language="JavaScript">
<!−−
alert("¡Hola, chicos!");
−−>
</script>
</head>
<body>
¡Bienvenidos a mi clase!
</body>
</html>
1
Las etiquetas <script> encierran una porción de código que contiene comandos para el cliente, conocida
como secuencia de comandos.
Hay dos lugares para ejecutar el código: en el servidor, donde todo se devuelve como HTML y en el cliente.
Estos dos lugares para el código son distintos y no tienen relación entre sí.
En el cliente:
No se procesa en el servidor. Se escribe en secuencias de comandos que indican al cliente que haga algo. Se
usa para realizar efectos dinámicos en el cliente como cuadros de mensaje.
En el servidor:
Se ejecuta sólo en el servidor. Todo se convierte en HTML o XML antes de enviarlo al cliente. Se utiliza para
procesar resultados y devolver datos.
Cómo enlaza ASP.NET los elementos
ASP.NET sabe lo que ocurre en el cliente porque éste se comunica con el servidor mediante una petición.
A través de las secuencias de comandos en el cliente, ASP.NET proporciona información de lo que éste hace
durante las peticiones.
Ejemplo:
Vas a una biblioteca y el bibliotecario en todo momento sabe lo que necesitas, si te caes te trae una venda, si
quieres leer te trae un libro, si tienes sed, agua ¿Cómo lo sabe? Tiene una red de espías que no dejan de
observarte aunque tú no lo sepas. Los espías son las secuencias de comandos en el cliente.
CREACIÓN DE PÁGINAS ASP.NET
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(obj as object, e as eventargs)
lblMensaje.Text = "¡Recíbeme con alegría soy tu profe de ASP.NET!"
End sub
</script>
<html><body>
<asp:Label id="lblMensaje" runat="server"/>
</body></html>
Un archivo sencillo, se puede escribir en un editor o en un block de notas. Hay que guardarlo en la carpeta
inetpub/root. Para visualizarla en el explorador: http://localhost/nombreCarpeta/NombrePagina.aspx.
2
ELEMENTOS DE UNA PÁGINA ASP.NET
<%@ Page Language="VB" %>
Directiva de página que da la información específica a la página ASP.NET. Nos dice que el lenguaje usado es
Visual Basic.
<script runat="server">
Sub tbMensaje_Change(Sender As Object, E As EventArgs)
lblMensaje.Text = "Hola, " + tbMensaje.Text + "."
End Sub
</script>
Bloque de declaración de código. Se parece al código en el lado del cliente, pero incluye la etiqueta
runat="server". Éste es el código que ASP.NET utiliza para procesar sus páginas y es donde controlaremos
la funcionalidad de la página.
Es mejor colocarlo entre las etiquetas <head> </head> auque pueden colocarse en cualquier parte de la
página.
<html><body>
Empieza la página HTML
<font size="5">Aprendiendo ASP.NET
Lección 2</font><hr><p>
<% Response.Write("Nuestra primera página<p>") %>
Éste es el bloque proveedor de código, empieza con <% . Contiene instrucciones que se usan para producir un
resultado. Muestra un texto en pantalla. Se van a usar con moderación porque no son compilados.
<form runat="server">
Tenemos un elemento HTML, pero con la etiqueta runat=server. Este formulario se convierte en formulario
web. Todo lo que contenga será vigilado por ASP.NET.
Por favor, teclea tu nombre:
<asp:textbox id="tbMensaje" OnTextChanged="tbMensaje_Change" runat=server/>
<asp:button id="btSubmit" Text="Enviar" runat=server/><p>
<asp:label id="lblMensaje" font−size="20pt" runat=server/>
Éstos son controles web. Funcionan de forma similar a los controles HTML, pero pueden usar ASP.NET.
Llevan la etiqueta runat=server
3
</form>
</body></html >
ASP y ASP.NET son totalmente distintos pero pueden operar en conjunto. Esto quiere decir que el servidor
web puede procesar tanto páginas ASP como ASP.NET.
EJERCICIO
Realizar una página que nos muestre un saludo por pantalla.
TEMA 2: CREACIÓN DE PÁGINAS ASP.NET
UNA APLICACIÓN SENCILLA
<%@ Page Language="VB" Debug="True" %>
<%@ Page Language="c#" Debug="True" %>
<script runat="server">
Sub tbMensaje_Change(Sender As Object, E As EventArgs)
lblMensaje.Text = "Hola, " + tbMensaje.Text + "."
End Sub
</script>
<script runat="server">
public void tbMensaje_Change (Object sender, EventArgs E)
{
lblMensaje.Text = "Hola, " + tbMensaje.Text + ".";
}
</script>
<html><body>
<font size="5">Aprendiendo ASP.NET Lección 2</font><hr><p>
<% Response.Write("Nuestra primera página<p>") %>
<% Response.Write("Nuestra primera página<p>"); %>
<form runat="server">
Por favor, teclea tu nombre:
4
<asp:textbox id="tbMensaje" OnTextChanged="tbMensaje_Change" runat=server/>
<asp:button id="btSubmit" Text="Enviar" runat=server/><p>
<asp:label id="lblMensaje" font−size="20pt" runat=server/>
</form>
</body></html >
Obtiene un valor del usuario y lo despliega con un saludo. No se ha establecido una acción en el formulario,
por lo que retorna a sí mismo.
<asp:textbox>,<asp:button>, <asp:label> son controles de servidor.
El atributo id es un nombre único que damos al control.
Todas las etiquetas deben tener apertura y cierre. Si no vamos a poner nada entre ellas podemos ponerlo así
<asp:textbox/>. Sin la etiqueta de cierre ASP.NET producirá errores.
El cuadro de texto tiene el atributo OnTextChanged=tbMensaje_Change. Tiene un evento que es
TextChanged. Hemos indicado a ASP.NET que ejecute el procedimiento tbMensaje_Change cuando ocurra
ese evento. Estos eventos se controlan en el servidor.
BLOQUES DE DECLARACIÓN DE CÓDIGO
<script runat="server">
Sub tbMensaje_Change(Sender As Object, E As EventArgs)
lblMensaje.Text = "Hola, " + tbMensaje.Text + "."
End Sub
</script>
<script runat="server">
public void tbMensaje_Change (Object sender, EventArgs E)
{
lblMensaje.Text = "Hola, " + tbMensaje.Text + ".";
}
</script>
La etiqueta <script> se utiliza en secuencias de comandos del cliente. Delimita una sección de la página que la
aplicación manejará de forma dinámica, conocida como bloque de declaración de código. No se convierte en
HTML dentro de la página, si no que contiene código que será ejecutado por el servidor. No olvidar incluir
runat=server.
5
Es mejor separar el bloque <script> tanto como sea posible del código de presentación o de HTML.
<% Response.Write("Nuestra primera página<p>") %>
Es equivalente a poner <%="Nuestra primera página<p>" %>
FLUJO DE PÁGINA
La primera vez que se solicita la página desde el explorador web ASP.NET compilará el código que esté en
los bloques de declaración. Por esto el explorador tarda en mostrar la página. Sin embargo, si se solicita una
segunda vez sin modificar el código no habrá retardo alguno. Pero si se modifica algo ASP.NET volverá a
compilar la página.
Una vez que se envía el formulario y se compila el código, ASP.NET empieza a procesar todo el código que
hemos generado y cualquier evento que haya ocurrido. En el ejemplo, el evento TextChanged ocurrió cuando
se tecleó algo en la caja de texto. El motor de ASP.NET explora este evento, determina que debe hacer y lo
hace.
En ese momento, ASP.NET convierte cualquier control en elemento HTML. Luego evalúa cualquier bloque
proveedor de código y devuelve el HTML necesario.
Por último, el HTML resultante se envía al explorador web, que recibe sólo HTML estándar. Por lo que
cualquier explorador web puede mostrar la página.
ESTADO VISUAL
Describe el aspecto de un objeto en un momento determinado. Por ej. Si un botón está o no pulsado. Una
aplicación que lleve el control de esta información se conoce como estado de conservación.
Si llenamos un formulario HTML y volvemos a él después, es posible que esté vacío. Esto es porque web es
un medio sin estado.
ASP.NET lleva automáticamente un control del estado visual. Esto quiere decir que si rellenamos un
formulario HTML y volvemos a él después los datos estarán allí.
ASP.NET hace esto al devolver campos ocultos de formulario HTML siempre que indicamos runat=server en
el formulario.
COMO ESCRIBIR CÓDIGO DE ASP.NET Y HTML
Hay dos formas de escribir código de ASP.NET: en los bloques de declaración de código o en los bloques
proveedores de código. Es mejor el primer método.
También hay varias formas de escribir HTML puro mediante ASP.NET, como con Response.Write o con la
etiqueta <%=.
Debemos: Separar el código ASP.NET del HTML tanto como podamos mediante bloques de declaración de
código.
No debemos: Utilizar bloques proveedores de código para intercalar código o resultados HTML (con
Response.Write) cuando otro método cumpla mejor con el trabajo.
6
COMENTARIOS EN EL CÓDIGO
Hay tres formas de comentar el código:
<!− − y − − > Para comentar sólo el código HTML.
` (apóstrofo) con Visual Basic
// /* comentario */ con c#
<%− − y − − %> comentarios para el servidor
COMO SE DIVIDE EN VARIAS LÍNEAS
Con Visual Basic:
<% Response.Write _
(hola) %>
<% Response.Write (Te estoy & _
saludando) %>
Con C#: No se hace nada especial.
COMO IMPORTAR ESPACIOS DE NOMBRES
<%@ Import Namespace=System.Drawing %> para VB
<%@ Import Namespace="System.Data" %> para c#
Importa todas las clases del espacio de nombre System.Drawing, como font e image.
De forma predeterminada, se importan automáticamente los siguientes a todas las páginas ASP.NET:
System
System.Collections
System.IO
System.Web
System.Web.IU
System.Web.IU.HtmlControls
System.Web.IU.WebConstrols
TEMA 3: USO DE OBJETOS EN ASP.NET
7
EL OBJETO RESPONSE
Permite la interacción del servidor con el cliente.
Cuando un usuario solicita una página asp.net genera una instancias del objeto HttpResponse, el cual
contiene información (propiedades y métodos) necesaria para comunicarse con el cliente. El nombre de la
instancia es Response, de modo que podrá utilizar este nombre para acceder a las propiedades y métodos del
objeto HttpResponse.
El método Write
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(obj as object, e as eventargs)
Dim i As Integer
Response.Write("Éste es un ejemplo")
Necesita una cadena como parámetro
Response.Write("<HR width=100%>")
For i = 1 To 5
Response.Write("<font size=" & i & ">¡Hola!<br></font>")
Next
End Sub
</script>
<html><body>
</body></html>
<%@ Page Language="c#" %>
<script runat="server">
public void Page_Load (Object sender, EventArgs E)
{
int i;
Response.Write("Éste es un ejemplo");
Response.Write("<HR width=100%>");
8
for ( i = 1;i<5;i++)
{
Response.Write("<font size=" + i + ">¡Hola!<br></font>");
}
}
</script>
<html><body>
</body></html>
VB.Net realiza cierta conversión de tipos de datos automáticamente. La conversión de un integer a string
podría servir como ejemplo. Es por ello que se puede utilizar Response.Write (6).
Pero c# no realiza la misma conversión automáticamente, por lo tanto, usar Response.Write (6) produciría un
error. Hay que usarlo así:
Response.Write (int.ToString(6))
COMO ALMACENAR PAGINAS EN EL BUFER
El almacenamiento en el búfer permite controlas en qué momento se enviará el resultado al explorador web.
Cuando se almacena el resultado en el búfer, no se envía nada al explorador web mientras no se ejecute todo
el código. Este es el método predeterminado en asp.net.
El almacenamiento en el búfer es un buen acelerador de rendimiento. Para desactivarlo:
BufferOutput=false.
<% Response.Buffer=False %>
Para controlar el búfer métodos Clear, Flush y End.
Clear: vacía el búfer
Flush: envía inmediatamente al explorador lo que hay en el búfer
End: evita que response envíe algo nuevo al explorador, sólo se envía la salida que haya actualmente en el
búfer.
EJERCICO: ANALIZAR LA SALIDA DE ESTE PROGRAMA
<%@ Page Language="VB" %>
<script runat="server">
9
Sub Page_Load(obj as object, e as eventargs)
Dim i As Integer
Response.Write("Antes de vaciar<br>")
Response.Flush()
For i = 0 To 5000
' Sólo para perder el tiempo
Next
Response.Write("Luego de vaciar, antes de limpiar<br>")
Response.Clear()
For i = 0 To 5000
' Sólo para perder el tiempo
Next
Response.Write("Luego de limpiar, antes de finalizar <br>")
Response.End()
For i = 0 To 5000
' Sólo para perder el tiempo
Next
Response.Write("Luego de finalizar<br>")
End Sub
</script>
<html><body>
</body></html>
<%@ Page Language="c#" %>
<script runat="server">
public void Page_Load (Object sender, EventArgs E)
{
10
int i;
Response.Write("Antes de vaciar<br>");
Response.Flush();
For (i = 0;i<500;i++)
{
// Sólo para perder el tiempo
}
Response.Write("Luego de vaciar, antes de limpiar<br>");
Response.Clear();
For (i = 0;i<500;i++)
{
// Sólo para perder el tiempo
}
Response.Write("Luego de limpiar, antes de finalizar <br>");
Response.End();
For (i = 0;i<500;i++)
{
// Sólo para perder el tiempo
}
Response.Write("Luego de finalizar<br>");
}
</script>
<html><body>
</body></html>
VER BUFFER.ASPX
COMO REDIRIGIR A LOS USUARIOS
11
Método Rediret.
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(obj as object, e as eventargs)
Response.Redirect(http://www.marian.com)
End Sub
</script>
<html><body>
¡Hola!
</body></html>
Cuando un usuario esta página, será enviado inmediatamente a www.marian.com y nunca verá el mensaje de
saludo.
Por ejemplo, es un método muy útil para enviar a un usuario a algún lugar de acuerdo con su login y su
password capturados en un formulario.
EL OBJETO REQUEST
Permite la interacción del explorador web con el servidor. El explorador envía información al servidor cuando
solita una página. Cuando esto ocurre, se genera un objeto HttpRequest para tratar con la información
enviada. Este objeto se llama Request. El objeto request representa la petición de un cliente, y el servidor web
envía una respuesta utilizando los objetos request y response.
COMO AVERIGUAR LA INFORMACIÓN DEL CLIENTE
Una función del objeto Request es obtener informació personal a través del explorador web, por ejemplo, lo
que ha capturado un usuario en un formulario o los valores de cadena de consulta, por ejemplo,
http://www.marian.com?id=yo&edad=33
La cadena de consulta, ?id=yo&edad=33, presenta los datos en forma de pares de valor, clave. El primer par
siempre está precedido de la ? y los siguientes separados por &.
Esta cadena es útil para pasar información de una página a otra.
Response.Redirect (mipagina.aspx?id=yo)
Sólo se pueden reconocer hasta 255 caracteres en esta cadena.
Request.Querystring devuelve id=yo&edad=33
Request.Querystring(id) devuelve yo
12
Request.Form devuelve todos los campos de un formulario
Request.Form (nombre) devuelve un valor indicado por nombre
Tanto las propiedades Querystring como Form representan colecciones de información.
Otras colecciones utilizadas por Request son ServerVariables y Cookies. La primera devuelve información del
servidor, como la IP o el protocolo http. La segunda devuelve información de las coookies.
Variables de entorno
URL .... el url de la página asp.net empezando después del servidor y nombre de dominio, después de
http://www.marian.com/
PATH_INFO lo mismo que url
PATH_TRANSLATED Toda la ruta física de asp.net en el servidor.
SERVER_NAME El nombre del servidor web
SERVER_SOFTWARE El nombre del software del servidor web. (Microsoft IIS 5.0)
EL OBJETO HttpCookie
Una cookie es un pequeño archivo en la computadora del usuario que contiene información específica para un
sitio web.
El objeto HttpCookie ofrece métodos para acceder y generar esas cookies. La forma común de manejar las
cookies es mediante los objetos Request y Response, los cuales cuentan con una propiedad Cookies que
devuelve una referencia a un objeto HttpCookie.
COMO GENERAR COOKIES
Dos formas de hacerlo:
Generar varias cookies, cada una con un valor en particular, o puede generar una cookie con diversos pares de
clave, valor.
Para vb:
Response.Cookies(MiCookie).Value=Una cookie
Response.Cookies(MiCookie2) (Usuario)=yo
Response.Cookies(MiCookie2) (edad)=33
En c#con [] en lugar de ()
Propiedad Expires para que la cookie quede inhabilitada cuando le digamos:
Response.Cookies(MiCookie2).Expires=DateTime.FromString(1/1/2005)
13
Response.Cookies(MiCookie2).Expires=DateTime.Now.AddMonths(1)
Para suprimir una cookie del cliente establecer expires a una fecha anterior o a 0.
Propiedades:
Domain: Restringe el uso de la cookie al dominio que le indiquemos.
Path: Similar a Domain, pero solo permite el acceso a la cookie a las páginas ASP.Net que se encuentren en
una ruta específica del servidor.
HasKeys:Indica si esta cookie tiene claves o es una cookie con un único valor.
Secure: Indica a Asp.net si debe o no transmitir la cookie de forma segura, es decir, sólo bajo el protocolo
HTTPS. El valor predeterminado es false.
COMO ACCEDER A LAS COOKIES
Utilizar el objeto Request
Response.Write (Request.Cookies (Micookie).Value)
Response.Write (Request.Cookies (Micookie2).(Usuario))
Para iterar por las claves de la cookie. La mayor parte del código se encuentra en el controlador de eventos
Page_Load.
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(obj as object, e as eventArgs)
Dim strVariable As String
' Establezco algunos valores de cookie
Response.Cookies("temp").Value = "HI"
Response.Cookies("CookieDe21la")("Nombreusuario") = "Tania"
Response.Cookies("CookieDe21la")("Preferencia") = _
"800x640"
Response.Cookies("CookieDe21la")("Contrasenia") = _
"QueInteresanteCookie"
Response.Cookies("CookieDe21la")("UltimaVisita") = _
DateTime.Now.ToString
14
Response.Cookies("CookieDe21la")("UserAgent") = _
Request.ServerVariables("HTTP_USER_AGENT")
Devuelve el valor del user Agent (Ej. Mozilla/4.0)
Devolvemos los valores de las cookies con ayuda de un bucle for... each.
for each strVariable in Response.Cookies _
("CookieDe21la").Values
Label1.Text += "<b>" & strVariable & "</b>: " & _
Request.Cookies("CookieDe21la")(strVariable) & "<br>"
next
end sub
</script>
<html><body>
<form runat="server">
<asp:Label id="Label1" runat="server"/>
</form>
</body></html>
<%@ Page Language="c#" %>
<script runat="server">
public void Page_Load (Object sender, EventArgs E)
{
string strVariable;
Response.Cookies["temp"].Value = "HI";
Response.Cookies["CookieDe21la"]["Nombreusuario"] = "Tania";
Response.Cookies["CookieDe21la"]["Preferencia"] = "800x640";
Response.Cookies["CookieDe21la"]["Contrasenia"] = "QueInteresanteCookie";
Response.Cookies["CookieDe21la"]["UltimaVisita"] = DateTime.Now.ToString;
15
Response.Cookies["CookieDe21la"]["UserAgent"] =
Request.ServerVariables("HTTP_USER_AGENT");
foreach (strVariable in Response.Cookies ["CookieDe21la"].Values)
{
Label1.Text += "<b>" + strVariable + "</b>: " +
Request.Cookies["CookieDe21la"](strVariable) + "<br>";
}
}
</script>
<html><body>
<form runat="server">
<asp:Label id="Label1" runat="server"/>
</form>
</body></html>
MÁS SOBRE COOKIES
Escritura de las cookies
Para escribir una cookie se utiliza la propiedad Response de la página, que muestra un objeto que permite
agregar datos a la información que la página envía al explorador. El objeto Response admite una colección
llamada Cookies, a la que agregará las cookies que desee escribir en el explorador.
Se pueden agregar cookies a la colección Response.Cookies de dos maneras diferentes. En el siguiente
ejemplo se muestran dos métodos para realizar esta tarea:
Response.Cookies("userName").Value = "mike"
Response.Cookies("userName").Expires = DateTime.Now.AddDays(1)
Dim aCookie As New HttpCookie("lastVisit")
aCookie.Value = DateTime.Now.ToString
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)
Response.Cookies["userName"].Value = "mike"
16
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(1)
Para crear una cookie con subclaves, puede utilizar una variación de la sintaxis que se utiliza para escribir una
cookie individual. En el siguiente ejemplo se muestran dos formas de escribir la misma cookie, ambas con dos
subclaves:
Response.Cookies("userInfo")("userName") = "mike"
Response.Cookies("userInfo")("lastVisit") = DateTime.Now.ToString
Response.Cookies("userInfo").Expires = DateTime.Now.AddDays(1)
Dim aCookie As New HttpCookie("userInfo")
aCookie.Values("userName") = "mike"
aCookie.Values("lastVisit") = DateTime.Now.ToString
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)
Response.Cookies["marian"]["BackColor"]="#99ccff";
Response.Cookies["marian"]["ForeColor"]="#0000cc";
Response.Cookies["marian"]["LinkColor"]="#ffcccc";
Response.Cookies["marian"]["FontSize"]="12pt";
Response.Cookies["marian"]["FontName"]="Comic Sans MS";
Response.Cookies["marian"].Expires=DateTime.Now.AddMonths(1);
<%@ Page Language="c#" %>
<script runat="server">
public void Page_Load(Object obj,EventArgs e)
{
HttpCookie aCookie = new HttpCookie("userInfo");
aCookie.Values["userName"] = "mike";
aCookie.Values["lastVisit"] = DateTime.Now.ToString();
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);
17
}
</script>
Limitar las cookies a una carpeta o aplicación
Para limitar las cookies a una carpeta del servidor, establezca la propiedad Path de éstas tal como se describe a
continuación:
Dim appCookie As New HttpCookie("AppCookie")
appCookie.Value = "Escrita " & Now.ToString
appCookie.Expires = Now.AddDays(1)
appCookie.Path = "/Application1"
Response.Cookies.Add(appCookie)
Limitar el ámbito de las cookies a un dominio
De forma predeterminada, las cookies se asocian a un determinado dominio. Por ejemplo, en el sitio
www.contoso.com, las cookies que escriba se enviarán al servidor cuando los usuarios soliciten cualquier
página de este sitio. (Excepto las cookies con un valor de ruta específico, tal como ya hemos visto en el
apartado anterior a éste). Si el sitio contiene subdominios por ejemplo, contoso.com, ventas.contoso.com y
soporte.contoso.com podrá asociar las cookies a un determinado subdominio. Para ello, establezca la
propiedad Domain de la cookie de la siguiente forma:
Response.Cookies("domain").Value = DateTime.Now.ToString
Response.Cookies("domain").Expires = DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain = "support.contoso.com"
Cuando el dominio se establece de este modo, la cookie únicamente estará disponible para las páginas del
subdominio que se haya especificado.
También puede utilizar la propiedad Domain para crear una cookie que puedan compartir varios subdominios.
Por ejemplo, establezca el dominio como se muestra a continuación:
Response.Cookies("domain").Value = DateTime.Now.ToString
Response.Cookies("domain").Expires = DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain = "contoso.com"
Lectura de las cookies
Cuando un explorador realiza una solicitud al servidor, envía junto con ésta las cookies para el servidor. En
las aplicaciones ASP.NET, puede leer las cookies mediante la utilización del objeto Request. La estructura del
objeto Request es básicamente la misma que la del objeto Response, por lo que puede leer las cookies del
objeto Request de un modo muy similar a cómo las escribió en el objeto Response. Los siguientes ejemplos
18
muestran dos modos de obtener el valor de una cookie llamada "userName" y mostrarlo en un control Label:
If Not Request.Cookies("userName") Is Nothing Then
Label1.Text = Server.HtmlEncode(Request.Cookies("userName").Value)
End If
If Not Request.Cookies("userName") Is Nothing Then
Dim aCookie As HttpCookie = Request.Cookies("userName")
Label1.Text = Server.HtmlEncode(aCookie.Value)
End If
Antes de intentar obtener el valor de una cookie, debe asegurarse de que ésta existe. De lo contrario, obtendrá
una excepción System.NullReferenceException. Observe igualmente que realizo una llamada al método
HttpServerUtility.HtmlEncode para codificar el contenido de una cookie antes de mostrarla en la página. El
motivo para que proceda de ese modo es que estoy mostrando el contenido de una cookie (algo que
generalmente no se hace) y quiero asegurarme de que un usuario malintencionado no haya introducido
secuencias de comandos ejecutables.
Asimismo, el valor de una subclave de una cookie se lee de un modo similar a como se configura. Esta es una
forma de obtener el valor de una subclave:
If Not Request.Cookies("userInfo") Is Nothing Then
Label1.Text = _
Server.HtmlEncode(Request.Cookies("userInfo")("userName"))
Label2.text = _
Server.HtmlEncode(Request.Cookies("userInfo")("lastVisit"))
End If
Lectura de las colecciones de cookies
En los ejemplos anteriores se asume que desea leer una determinada cookie cuyo nombre ya conoce. Puede
que en ocasiones deba leer todas las cookies disponibles para la página. Para leer los nombres y valores de
todas estas cookies puede recorrer la colección Request.Cookies utilizando código como éste:
Dim i As Integer
Dim output As String = ""
Dim aCookie As HttpCookie
For i = 0 to Request.Cookies.Count − 1
19
aCookie = Request.Cookies(i)
output &= "Nombre de cookie = " & Server.HtmlEncode(aCookie.Name) & "<br>"
output &= "Valor de cookie = " & Server.HtmlEncode(aCookie.Value) & _
& "<br><br>"
Next
Label1.Text = output
Request.Cookies["marian"]["FontSize"]
Request.Cookies["marian"].Value
Nota Cuando ejecute este código, probablemente verá una cookie llamada "ASP.NET_SessionId". Se trata de
una cookie que ASP.NET utiliza para almacenar un identificador único para su sesión y que no se guardará en
el disco duro de su equipo.
Comprobar si un explorador acepta cookies
Sub Page_Load()
If Not Page.IsPostBack Then
If Request.QueryString("AcceptsCookies") Is Nothing Then
Response.Cookies("TestCookie").Value = "ok"
Response.Cookies("TestCookie").Expires = _
DateTime.Now.AddMinutes(1)
Response.Redirect("TestForCookies.aspx?redirect=" & _
Server.UrlEncode(Request.Url.ToString))
Else
labelAcceptsCookies.Text = "Aceptar cookies = " & _
Request.QueryString("AcceptsCookies")
End If
End If
End Sub
EJERCICIO:
20
Mediante el uso de Cookies personalizar la página del cliente.
Al pulsar personalizar aparece:
21
Seleccionamos y mostramos el resultado:
22
(Solución ejercicio Tema3−cookies−mariancookies)
EL OBJETO PAGE
Contiene todas las propiedades y métodos de toda la página asp.net que genere. Cuando ejecutamos una
página asp.net ésta heredará de la clase Page del .NET Framework
Herencia: Una clase define algunos parámetros y métodos para los objetos que se basen en ella. Cuando
genere otra clase que se herede de la principal, también heredará sus miembros. También podemos generar sus
propios miembros en la clase secundaria.
Las páginas asp.net son los objetos secundarios del objeto Page. Cualquier método o propiedad que defina en
la página asp.net se convertirá en miembro del objeto basado en su página. Esto significa que si genero otra
página podré acceder a los métodos y propiedades de la primera.
Miembros útiles integrados:
23
IsPostBack: Indica si un formulario de esta página fue enviado a la misma.
DataBind: Enlaza todas las expresiones de datos a los controles de la página.
Evento Load: Se desencadena cuando la página comienza a cargarse en el explorador.
Eventos:
Init: este evento es lanzado cuando la página es inicializada, cuando es lanzado este evento todavía no se han
creado por completo los distintos controles de la página. Este evento es tratado en el método Page_Init.
Load: este evento se lanzaría a continuación del método Init y es lanzado cuando la página se ha cargado, en
este caso todos los controles de la página ya han sido creados. Este evento se lanzará cada vez que la página
ASP .NET es ejecutada. Este evento es tratado en el método Page_Load.
PreRender: el evento se lanzará justo antes de enviar la información al cliente. Este evento es tratado en el
método Page_PreRender, y siempre es lanzado después del evento Load.
UnLoad: este otro evento se lanzará en último lugar, y tiene lugar cuando la página ha finalizado de
procesarse, es decir, cuando se ha terminado la ejecución de la página y toda la información ha sido enviada al
cliente. Este evento es tratado en el método Page_UnLoad.
Error: este evento se lanzará cuando se produzca una excepción no tratada dentro de la página. El método
Page_Error se utilizará cuando deseemos realizar nuestro propio tratamiento de errores, esto lo veremos más
en detalle en el capítulo dedicado al tratamiento de errores y depuración.
Propiedades:
IsPostBack: esta propiedad de la clase Bolean devolverá true si la página ASP .NET actual ya ha sido enviada
al servidor en alguna ocasión. Si tiene el valor false indicará que la página es la primera vez que se carga y
nos servirá de indicador para poder inicializar los controles Web de la página o bien realizar otras labores de
inicialización.
Application: esta propiedad nos va a ofrecer una referencia a un objeto de la clase
System.Web.HttpApplicationState, este objeto nos va a permitir almacenar y acceder a información que va a
ser común a toda la aplicación Web, es decir, es una información compartida por todos los clientes de una
aplicación Web determinada. Esta propiedad es equivalente al objeto integrado Application de anteriores
versiones de ASP.
Uso del evento Page_Load. Analiza este código
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(obj as object, e as eventArgs)
tbMyText.Value = "¡Éste es el evento Page_Load!"
End Sub
</script>
24
<html><body>
<form runat="server">
<input type="text" size="25"
id="tbMyText" runat="server" />
</form>
</body></html>
<%@ Page Language="c#" %>
<script runat="server">
public void Page_Load (Object sender, EventArgs E)
{
tbMyText.Value = "¡Éste es el evento Page_Load!";
}
</script>
<html><body>
<form runat="server">
<input type="text" size="25"
id="tbMyText" runat="server" />
</form>
</body></html>
En el evento Load se verifica la identidad del usuario, se cargan los datos de una base de datos y se redirige al
usuario, por ejemplo.
Ejemplo de formatos de fechas correctas para DateTime:
<%@ Page Language="VB" %>
<script runat="server">
sub Page_Load(obj as object, e as eventArgs)
Dim Ahora as DateTime = DateTime.Now
Dim intHora as Integer = Ahora.Hour
25
Label1.Text = "En este momento son " & _
Ahora.ToString("d") + "<p>"
Label1.Text += Ahora.ToString("D") + "<p>"
Label1.Text += Ahora.ToString("f") + "<p>"
Label1.Text += Ahora.ToString("F") + "<p>"
Label1.Text += Ahora.ToString("g") + "<p>"
Label1.Text += Ahora.ToString("G") + "<p>"
Label1.Text += Ahora.ToString("m") + "<p>"
Label1.Text += Ahora.ToString("r") + "<p>"
Label1.Text += Ahora.ToString("s") + "<p>"
Label1.Text += Ahora.ToString("t") + "<p>"
Label1.Text += Ahora.ToString("T") + "<p>"
Label1.Text += Ahora.ToString("u") + "<p>"
Label1.Text += Ahora.ToString("U") + "<p>"
Label1.Text += Ahora.ToString("y") + "<p>"
Label1.Text += Ahora.ToString("dddd, MMMM dd yyyy") + "<p>"
Label1.Text += Ahora.ToString("ddd, MMM d ""'""yy") + "<p>"
Label1.Text += Ahora.ToString("dddd, MMMM dd") + "<p>"
Label1.Text += Ahora.ToString("M/yy") + "<p>"
Label1.Text += Ahora.ToString("dd−MM−yy") + "<p>"
if intHora < 12 then
Label1.Text += "¡Buenos días!"
elseif intHora > 12 And intHora < 18 then
Label1.Text += "¡Buenas tardes!"
else
Label1.Text += "¡Buenas noches!"
26
end if
end sub
</script>
<html><body>
<form runat="server">
<asp:Label id="Label1" runat="server"/>
</form>
</body></html>
Ejercicio:
Mostrar al usuario distintos mensajes dependiendo de la hora a la que se conecte, en C#
Solución Tema3−fechas
Archivo Global.asax
Además de escribir código para interfaces de usuario, los programadores también pueden agregar lógica del
nivel de aplicación y código de control de eventos a sus aplicaciones Web. Este código no se encarga de
generar interfaces de usuario y no se invoca normalmente en respuesta a solicitudes de páginas individuales.
En vez de ello, se encarga de procesar eventos de la aplicación de nivel superior, tales como
Application_Start, Application_End, Session_Start, Session_End, etc. Los programadores crean esta
lógica mediante un archivo Global.asax ubicado en la raíz del árbol de directorios virtuales de una aplicación
Web. ASP.NET analiza y compila automáticamente este archivo para producir una clase dinámica de .NET
Framework, la cual extiende la clase base HttpApplication (la primera vez que se activa o se solicita
cualquier recurso o URL dentro del espacio de nombres de la aplicación).
ASP.NET analiza y compila dinámicamente el archivo Global.asax para producir una clase de .NET
Framework la primera vez que se activa o se solicita cualquier recurso o URL dentro del espacio de nombres
de la aplicación. El archivo Global.asax está configurado para rechazar automáticamente cualquier solicitud
de URL directa de modo que los usuarios externos no puedan descargar o ver el código interno.
Eventos cuyo ámbito es una sesión o una aplicación
Los programadores pueden definir controladores para eventos de la clase base HttpApplication creando
métodos en el archivo Global.asax que se ajusten al modelo de nomenclatura
"NombreDeEventoDeLaAplicación(FirmaDeArgumentosDelEvento)". Por ejemplo:
<script language="C#" runat="server">
void Application_Start(object sender, EventArgs e)
{
// Application startup code goes here
27
}</script>
Si el código de control de eventos necesita importar espacios de nombres adicionales, se puede utilizar la
directiva @ import en una página .aspx, como se indica a continuación:
<%@ Import Namespace="System.Text" %>
El siguiente ejemplo ilustra el período de vida de Application, Session y Request.
Ver ejemplo Tema3−global
La primera vez que se abre la página, se provoca el evento Start para la aplicación y la sesión:
void Application_Start(object sender, EventArgs e) {
// Application startup code goes here
}
void Session_Start(object sender, EventArgs e) {
Response.Write("Session is Starting...<br>");
Session.Timeout = 1;
}
Los eventos BeginRequest y EndRequest se provocan en cada solicitud. Cuando la página se actualiza, sólo
aparecen mensajes de BeginRequest, EndRequest y el método Page_Load. Observa que, al abandonar la
sesión actual (hacer clic en el botón "Finalizar esta sesión"), se crea una nueva sesión y se provoca de nuevo
el evento Session_Start.
Sub Application_Start(Sender As Object, E As EventArgs)
' Application startup code goes here
End Sub
Sub Session_Start(Sender As Object, E As EventArgs)
Response.Write("Session is Starting...<br>")
Session.Timeout = 1
End Sub
function Application_Start(sender:Object, E:EventArgs) : void {
// Application startup code goes here
}
28
function Session_Start(sender:Object, e:EventArgs) : void {
Response.Write("Session is Starting...<br>");
Session.Timeout = 1;
}
EL OBJETO SESSION
Debido a que Web es un medio sin estado es difícil llevar un control de la información del usuario. No hay
forma de utilizar http para saber si una serie de peticiones proviene de un usuario o de varios.
El objeto Session permite almacenar elementos propios de un usuario, como variables, objetos, cadenas...) en
un solo lugar del servidor. Al tiempo que un usuario pasa en un sitio se le conoce como sesión.
Explicar este código:
<%@ Page Language="VB" %>
<%@ Page Language="c#" %>
<script runat="server">
Sub Enviar_Click(obj as object, e as EventArgs)
If tbNombre.Value <> ""
Session("Nombre") = tbNombre.Value
Response.Write("¡Hola, " & Session("Nombre") & "!")
Else
Response.Write("Olvidó capturar un nombre.")
End if
End Sub
public void Enviar_Click (Object sender, EventArgs E)
{
if(tbNombre.Value != "")
{
Session["Nombre"] = tbNombre.Value ;
Response.Write("¡Hola, " + Session["Nombre"] + "!") ;
29
}
else
{
Response.Write("Olvidó escribir un nombre.");
}
}
</script>
<html><body>
<form runat="server">
Por favor, teclee su nombre:
<input type="text" id="tbNombre" runat="server"/>
<p>
<asp:Button id="btEnviar" text="Enviar"runat="server" OnClick="Enviar_Click" />
</form>
</body></html>
COMO RECUPERAR VARIABLES DE SESSION
<%@ Page Language="VB" %>
<script runat="server">
sub Page_Load(obj as object, e as eventArgs)
Etiqueta1.Text = "¡Bienvenido de vuelta " & Session("Nombre") & "!"
end sub
</script>
<html><body>
<form runat="server">
<asp:Label id="Etiqueta1" runat="server"/>
</form>
30
</body></html>
<%@ Page Language="c#" %>
<script runat="server">
public void Page_Load(Object obj, EventArgs e)
Etiqueta1.Text = "¡Bienvenido de vuelta " + Session["Nombre"] + "!" ;
}
</script>
<html><body>
<form runat="server">
<asp:Label id="Etiqueta1" runat="server"/>
</form>
</body></html>
Ver ejemplo − tema3\sesion\ejemploSesion
¿Cómo logra asp.net llevar un control de las sesiones? Cuando un usuario visita el sitio e inicia sesión, el
equipo genera un identificador único para él que almacena en el equipo cliente en forma de cookie.
Response.Write(Session.SessionID)
Cuando la sesión expire se eliminará la cookie.
CONTROL DE SESSION
Timeout: Tiempo que puede estar inactiva una sesión antes que asp.net la deje. 20 minutos es el valor
predeterminado.
Para modificarlo: Session.Timeout= x donde x es el tiempo en minutos
Session.Abandon: hace que la sesión termine.
USO DE SESSION
Se usa como cualquier matriz.
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(obj as object, e as eventArgs)
31
Dim strVariable As String
' Establezco algunas variables de sesión
Session("Nombre") = "Tania"
Session("ColorFavorito") = "Naranja"
Session("ColorOjos") = "Café"
Session("UnMensaje") = "Bienvenido a mi mundo."
Session("ASPNET") = "¡Es a genial!"
For Each strVariable In Session.Contents
Label1.Text += "<b>" & strVariable & "</b>: " & _
Session(strVariable) & "<br>"
Next
End Sub
</script>
<html><body>
<form runat="server">
<asp:Label id="Label1" runat="server"/>
</form>
</body></html>
<%@ Page Language="C#" %>
<script runat="server">
public void Page_Load(object obj, eventArgs e){
string strVariable;
' Establezco algunas variables de sesión
Session["Nombre"] = "Tania"
Session["ColorFavorito"]= "Naranja"
Session["ColorOjos"] = "Café"
32
Session["UnMensaje"] = "Bienvenido a mi mundo."
Session["ASPNET"] = "¡Es genial!"
foreach (strVariable In Session.Contents){
Label1.Text += "<b>" + strVariable + "</b>: " + Session[strVariable] + "<br>"
}
}
</script>
<html><body>
<form runat="server">
<asp:Label id="Label1" runat="server"/>
</form>
</body></html>
Si el usuario no soporta cookies asp.net coloca el identificador de la sesión cifrado en cada vínculo de la
página.
Es posible almacenar los datos con ámbito de sesión a fin de proporcionar datos individuales a un usuario
durante una sesión. En el ejemplo siguiente se inicializan los valores de preferencias de usuario en el evento
Session_Start del archivo Global.asax.
void Session_Start() {
Session["BackColor"] = "beige";
...
}
Se modifican los valores de las preferencias de usuario en el controlador de eventos Submit_Click con la
información aportada por el usuario.
protected void Submit_Click(Object sender, EventArgs e) {
Session["BackColor"] = BackColor.Value;
...
}
Configurar el estado de una sesión: es posible configurar las características del estado de una sesión en la
sección <sessionState> de un archivo web.config. Para doblar el tiempo de espera predeterminado de 20
33
minutos, se puede agregar el código siguiente al archivo web.config de una aplicación:
<sessionState timeout=40 />
Protected GetStyle(key As String) As String
Return(Session(key).ToString())
End Sub
protected function GetStyle(key:String) : String {
return Session(key).ToString();
}
Sub Session_Start()
Session("BackColor") = "beige"
...
End Sub
function Session_Start() : void {
Session("BackColor") = "beige";
...
}
EJERCICIO:
Realizar el mismo ejercicio de las cookies pero con variables de sesión.
Solución:tema3−sesion−mariansesion1
EL OBJETO HttpApplication
Aplicación: Conjunto de archivos que hay en un directorio virtual y sus subdirectorios.
ASP.net genera un objeto HttpApplication llamado Application cuando arranca su aplicación, es decir, cuando
alguien solicita la página por primera vez.
Sólo se genera un objeto Application para toda la aplicación. Al igual que Session puede usarse para
almacenar variables y objetos. Por ejemplo un pie de página que vamos a colocar en cada página.
Application(pie)=Derechos de autor 2004
Escribiríamos en cada página:
34
Response.Write(Application(pie))
EL OBJETO HttpSeverUtility
Podemos utilizar el nombre Server para acceder a los miembros de este objeto.
COMO REDIRIGIR A LOS USUARIOS
Con el objeto Response.
Con los métodos Execute y Transfer del objeto HttpSeverUtility.
Server.Transfer lleva la ejecución a otra página.
If (strContraseña == micontraseña) Server.Transfer(PuedoEntrar.aspx)
Server.Execute lleva la ejecución de asp.net as otra página, pero regresa a la misma cuando termine. Esto es
útil si se necesita ejecutar cierto código en otra página (como un procesamiento de datos) pero continuar en la
misma página.
COMO DAR FORMATO A LAS CADENAS
Cuando envíe alguna salida al explorador, será interpretada como HTML.
Response.Write (<br>)
Si en lugar de un salto de línea quiero que aparezca <br> usaré el método HtmlEncode del objeto
HttpServerUtility. Esto daría como resultado <br> y el usuario vería <br> en el explorador.
UrlEncode hace algo similar, pero da formato a una cadena en particular con las reglas URL. Por ejemplo el
& y ? tienen un significado especial en un url.
Server.HtmlDecode y Server.UrlDecode realizan estas operaciones a la inversa.
El método MapPath traduce una ruta virtual en una física en el servidor.
Server.MapPath(/asp/tema4)
Se traduce en
C:\inetpub\wwwroot\asp\tema4
COMO CONTROLAR SECUENCIAS DE COMANDOS
Con el método ScriptTimeout indicamos el tiempo que vamos a esperar antes de finalizar la secuencia de
comandos.
Por ejemplo si escribimos un código con un bucle infinito....
Server.ScriptTimeout=90 (segundos)
COMO GENERAR OBJETOS
35
Con el método CreateObject creamos una instancia de un objeto COM.
EJERCICIOS:
• Generar una página ASP.NET en C# que actúe como inicio de sesión seguro. Permita que el usuario
capture un nombre y una contraseña en el cuadro de texto. Si concuerdan con una cadena que
indiquemos, redirigiremos al usuario a una página de aceptación, de otro modo, mostramos un error.
Si el nombreusuario es válido, guardar en una variable de sesión.
• Escribir una página de aceptación. Mostar un mensaje de bienvenida adaptado para el usuario con
ayuda del evento Load del objeto Page y un control Label. Indicar al usuario la hora en curso y su
identificador de sesión. Verificar la propiedad IsPostback del objeto Page para asegurarse de que
este mensaje sólo aparece la primera vez que el usuario llegue a la página. Agregar un botón para
que pueda finalizar la sesión, con un mensaje de confirmación.
Soluciones: tema3/tema3ej1y2
TEMA 4: INTRODUCCIÓN A LOS FORMULARIOS WEB
Permiten un control programático de la interfaz del usuario mediante el uso de objetos residentes en el
servidor.
PRESENTACIÓN DE LOS FORMULARIOS
Un cliente envía una petición a un servidor para obtener cierta información y que éste responda a su envío. Es
el modelo petición−respuesta.
<html><body>
<form method ="post">
Teclea tu nombre
<input type="text" size= 20>
<input type="Submit" Value=enviar>
</form>
</body></html>
El cliente también puede enviar datos al servidor. Los formularios HTML permiten la interacción del usuario
con páginas web.
Cuando el usuario hace clic en el botón Enviar, el formulario envía al servidor los datos que haya capturado.
Los formularios HTML se basan por completo en el cliente. Entre el cliente y el servidor es difícil
intercambiar información. Tan pronto como el servidor envía los datos, olvida todo lo que el formulario indica
y pierde el rastro de lo que sucede.
PRESENTACIÓN DE LOS FORMULARIOS WEB
Son muy similares a los HTML. La diferencia es que se basan en el servidor. Genera los elementos del
36
usuario en el servidor. El servidor tendrá conocimiento de la apariencia de la interfaz, qué puede hacer, qué
datos recibirá, etc.
En el servidor generaremos objetos llamados controles de servidor, que pueden controlarse por completo:
tienen propiedades, eventos y métodos que podemos manejar. Tan pronto como el cliente solicita la página,
ASP.NET convierte los controles a HTML.
A través de la secuencia de comandos que asp.net genera automáticamente en el cliente, estos controles avisan
al servidor cuando algo sucede, como cuando se hace clic en un botón.
MODELO DE PROGRAMACIÓN DE LOS FORMULARIOS WEB
Los formularios web están divididos en dos partes: los elementos visuales y la lógica de la interfaz. Están
separados entre sí en el plano conceptual y en el físico.
CONTROLES DE SERVIDOR
Los controles ASP .NET son una serie de objetos de servidor que generarán el correspondiente código HTML
para que el usuario pueda utilizarlos en la página cargada en su navegador al ejecutarse la página ASP .NET
correspondiente los controles de servidor de ASP .NET generarán todo el código equivalente en el lenguaje
HTML, para que así pueda ser interpretado el resultado de la ejecución de la página por cualquier navegador
Web.
Cada control se corresponde con una clase determinada perteneciente a un espacio con nombre determinado.
Existe un gran número de controles de servidor y cada uno de ellos pertenece a una clase del .NET
Framework.
Son los elementos de la interfaz de usuario de un formulario web. Hay cuatro tipos de estos controles en
asp.net:
controles HTML de servidor,
controles web,
controles de validación,
controles de usuario.
Los controles HTML de servidor representan a los elementos normales de los formularios HTML, como los
cuadros de texto y los botones, pero se crean en el servidor donde podemos controlarlos.
Los controles web son semejantes, pero ofrecen una mayor funcinalidad y pueden representar interfaces de
usuario más complejas.
Los controles de validación se utilizan para validar lo capturado por el usuario.
Los controles de usuario son aquellos programados a medida para realizar cierta funcionalidad.
Todos tienen propiedades, métodos y eventos.
EVENTOS DE LOS CONTROLES DE SERVIDOR
37
Hacer clic en un botón, en un vínculo, llenar un cuadro de texto, seleccionar un elemento de una lista....
Un evento activo necesita una acción explícita del usuario. Un evento pasivo se puede ejecutar sin intención
directa del usuario, como mover el cursor por una imagen.
Sólo los eventos activos se manejan en el servidor.
Hay dos formas de enviar los eventos al servidor: conforme ocurren o todos juntos en un solo envío. Es
conveniente utilizar el segundo método. Permanecen en la caché del usuario hasta que éste se decida a enviar
los datos.
Los controles generan eventos automáticamente siempre que sucede algo. Para controlar el evento en el
servidor, necesitará indicar al control qué método utilizar.
<%@ Page Language="VB" %>
<script runat="server">
Sub Button1_Click(obj as object, e as EventArgs)
Label1.Text="Hizo clic en <b>" & obj.Text & "</b>"
Esta línea establece la propiedad Text del control Label1.
Esta línea da el mismo resutado:
Label1.Text="Hizo clic en <b>" & Button1.Text & "</b>"
End Sub
</script>
<html><body>
<font size="5"> Tema 4</font><hr><p>
<form runat="server">
<asp:Button id=Button1 runat="server" Text="Botón1"
onClick="Button1_Click" />
<p>
<asp:Label id=Label1 runat=server />
</form>
</body></html>
<%@ Page Language="c#" %>
38
<script runat="server">
public void Button1_Click(Object obj, EventArgs e)
{
Label1.Text="Hizo clic en <b>" + ((Button)obj).Text + "</b>";
}
</script>
<html><body>
<font size="5"> Tema 4</font><hr><p>
<form runat="server">
<asp:Button id=Button1 runat="server" Text="Botón1"
onClick="Button1_Click" />
<p>
<asp:Label id=Label1 runat=server />
</form>
</body></html>
Ver tema4−tm4ejemplo1.aspx
Si especificamos en el controlador del servidor que un método deberá controlar un evento:
<asp:Button runat=server OnClick=UnMetodo />
Si no genero este método en alguna parte del bloque de declaración de código, recibiré un error.
COMO ENVIAR FORMULARIOS WEB
Una situación típica, cuando la página se cargue en el explorador, mostramos un mensaje de bienvenida en un
control de servidor. Este mensaje formará parte del estado visual del control y asp.net lo recordará siempre.
El objeto Page tiene una propiedad llamada IsPostBack que informa si el formulario ya ha sido o no enviado.
Se puede verificar esta propiedad y decidir si se llena o no con los controles de servidor.
Ejemplo:
<%@ Page Language="VB" %>
<script runat="server">
39
Sub Page_Load(obj as object, e as EventArgs)
If Not Page.IsPostBack Then
lblMensaje.Text = "¡Hola, mundo!"
End If
End Sub
Evalúa la propiedad IsPostBack, y si es verdadera(el formulario ha sido enviado) no ejecuta la siguiente línea.
Asp.net llenará la etiqueta por ti cada vez que el formulario se envía.
Sub Enviar(obj as object, e as EventArgs)
lblMensaje2.Text = "Formulario enviado."
End Sub
</script>
<html><body>
<form runat="server">
<asp:Button id="btEnviar" runat="server" Text="Enviar"
onClick="Enviar" />
<p>
<asp:Label id="lblMensaje" runat=server />
<p>
<asp:Label id="lblMensaje2" runat=server />
</form>
</body></html>
<%@ Page Language="c#" %>
<script runat="server">
public void Page_Load (Object sender, EventArgs E)
{
if (!Page.IsPostBack)
{
40
lblMensaje.Text = "¡Hola, mundo!";
}
}
Evalúa la propiedad IsPostBack, y si es verdadera (el formulario ha sido enviado) no ejecuta la siguiente línea.
Asp.net llenará la etiqueta por ti cada vez que el formulario se envía.
public void Enviar (Object sender, EventArgs E)
{
lblMensaje2.Text = "Formulario enviado.";
}
</script>
<html><body>
<form runat="server">
<asp:Button id="btEnviar" runat="server" Text="Enviar" onClick="Enviar"/>
<p>
<asp:Label id="lblMensaje" runat=server />
<p>
<asp:Label id="lblMensaje2" runat=server />
</form>
</body></html>
Ver tema4−tm4ejemplo2.aspx
COMO GUARDAR EL ESTADO
Los formularios web guardan el estado visual de cada control en el formulario mediante campos ocultos. Este
estado visual le indica lo que se ha tecleado en el control, ya sea que éste se encuentre o no seleccionado, qué
elemento lo está, etc
Hay otra forma de guardar información en los formularios web. Utilizar el saco de estado o state bag, un
objeto que contiene los valores cuando se envía un formulario. Cuando coloca algo en el saco de estado y
envías el formulario, el servidor guarda la información y la devuelve al cliente cuando finaliza su proceso. Es
una forma sencilla de almacenar información personalizada que un usuario no haya tecleado, por ejemplo un
cálculo. Se accede al saco de estado mediante la variable ViewState.
Ejemplo: Guardar la hora en curso en el saco de estado tan pronto como se carga la página. Cuando el usuario
41
hace clic en el botón Enviar, se compara la hora de inicio con la nueva hora.
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(obj as object, e as EventArgs)
If Not Page.IsPostBack then
ViewState("HoraInicio") = DateTime.Now
lblMensaje.Text = "Ahora son: " & _
ViewState("HoraInicio")
End If
End Sub
Como se necesita almacenar la hora la primera vez que se accede a la página, tenemos que verificar la
propiedad IsPostBack. Si es el primer acceso almacenamos la hora en la variable ViewState.
Sub Enviar(obj as object, e as EventArgs)
lblMensaje.Text = "Ahora son: " & _
DateTime.Now & "<br>iniciado a las: " & _
ViewState("HoraInicio")
End Sub
</script>
<html><body>
<font size="5">Aprendiendo ASP.NET </font><hr><p>
<form runat="server">
<asp:Button id="btEnviar" runat="server" Text="Enviar"
onClick="Enviar" />
<p>
<asp:Label id="lblMensaje" runat=server />
</form>
</body></html>
42
<%@ Page Language="c#" %>
<script runat="server">
public void Page_Load (Object sender, EventArgs E)
{
if (!Page.IsPostBack)
{
ViewState["HoraInicio"] = DateTime.Now;
lblMensaje.Text = "Ahora son: " + ViewState["HoraInicio"];
}
}
Como se necesita almacenar la hora la primera vez que se accede a la página, tenemos que verificar la
propiedad IsPostBack. Si es el primer acceso almacenamos la hora en la variable ViewState.
public void Enviar(Object sender, EventArgs E)
{
lblMensaje.Text = "Ahora son: " +
DateTime.Now + "<br>iniciado a las: " +
ViewState["HoraInicio"];
}
</script>
<html><body>
<font size="5">Aprendiendo ASP.NET </font><hr><p>
<form runat="server">
<asp:Button id="btEnviar" runat="server" Text="Enviar"
onClick="Enviar" />
<p>
<asp:Label id="lblMensaje" runat=server />
</form></body></html>
43
(ver tema4−estado)
EJERCICIO:
44
45
46
Solución: tema−saco−prueba3
ORDEN DE PROCESAMIENTO DE LOS FORMULARIOS WEB
1 La página se solicita (o envía)
2 Se restaura el estado visual de los controles
3 Ocurre el evento Page_Load
4 Los eventos se controlan, se ejecutan los métodos que controlan eventos.
5 Ocurre el evento Page_Unload
CONTOLES HTML DE SERVIDOR
Los controles HTML ofrecen a los desarrolladores de entornos Web la potencia de los Web Forms
47
manteniendo la familiaridad y facilidad de uso de las etiquetas HTML que representan los campos de un
formulario.
Estos controles tienen el mismo aspecto que una etiqueta HTML a excepción de que presentan el atributo
runat con el valor server.
Si queremos realizar el tratamiento de eventos con código del servidor, utilizaremos el atributo
onserverevento, a este atributo se le indica como valor el nombre del método que queremos ejecutar.
Los elementos HTML están totalmente basados en el cliente. Un explorador conoce el aspecto y
funcionamiento de <input type=text> y lo interpreta de acuerdo con eso.
Los controles HTML de servidor son elementos u objetos que se crean en éste, con propiedades, métodos y
eventos que podemos controlar.
Son muy fáciles de generar: sólo hay que agregar el atributo runat=server a cualquier elemento HTML.
Todos estos controles pertenecen al espacio de nombres System.Web.UI.HtmlControls.
<%@ Page Language="VB" %>
<script runat="server">
Sub Clic(obj as object, e as EventArgs)
select case obj.Value
case "Izquierda"
word_image.align = "left"
case "Derecha"
word_image.align = "right"
case "Centro"
word_image.align = "center"
end select
Aquí establezco el estilo de los botones. Quiero que el botón que fue oprimido aparezca sumido. Por eso hay
que sacar el resto con el valor notset.
Izquierda.Style("Border−Style") = "notset"
Derecha.Style("Border−Style") = "notset"
Centro.Style("Border−Style") = "notset"
Establezco a inset la propiedad del botón representado por obj.
48
obj.Style("Border−Style") = "inset"
end Sub
</script>
Aquí tenemos 6 elementos HTML: un formulario, tres botones, una imagen y una sección <div>.
Los controles HtmlInputButton (botones) tienen un evento llamado ServerClick, que sucede cuando se
oprimen.
<html><body>
<font size="5">Aprendiendo ASP.NET: </font><hr><p>
<form runat="server">
<input type="Button" id="Izquierda" runat="server"
Value="Izquierda" OnServerClick="Clic" />
<input type="Button" id="Centro" runat="server"
Value="Centro" OnServerClick="Clic" />
<input type="Button" id="Derecha" runat="server"
Value="Derecha" OnServerClick="Clic" />
</form>
<img src="carita.jpg" id="word_image" runat="server">
<div id="Label1" runat="server">Éste es un texto de ejemplo. Cuando los botones de arriba se opriman, la
imagen se moverá por el texto para acomodarse en la posición elegida.<p> Este ejemplo
demuestra los controles HtmlImage y HtmlInputButton.
</div>
</body></html>
Ver ejercicios/tema4/caritavb/prueba4vb.aspx
EJERCICIO
Realizar ese mismo ejercicio con C#.
Solución: ejercicios/tema4/caritaCsharp
HtmlAnchor :
49
Esta clase se corresponde con la etiqueta <a>, es decir, es el control HTML que nos permite manejar enlaces.
El elemento HTML <a> permite crear un hipervínculo para desplazarse a otra ubicación de la página o a otra
página Web.
HmlButton :
Este control HTML generará la etiqueta <button> de HTML
Esta control HTML se utilizará cuando sea necesario personalizar al máximo el aspecto de un botón permite
incluir texto con formato, imágenes u otros controles de formularios Web Forms.
HtmlForm :
Esta clase representa a la etiqueta <form> en el servidor, es la que permite definir un Web Form, que va a
realizar la labor de contenedor para una serie de controles de servidor dentro de la página ASP .NET. Todos
los controles ASP .NET que deseemos enviar al servidor (post) debemos incluirlos dentro de un control de la
clase HtmlForm.
HtmlGenericControl :
Esta clase se utilizará para representar las etiquetas HTML que no poseen una correspondencia directa con las
clases del .NET Framework, como puede suceder con las etiquetas <span>, <div> o <body>, entre otras.
HtmlImage :
Esta clase permite utilizar la etiqueta <img> de HTML en el servidor, es decir, el control <img runat=server>.
Nos permite por lo tanto manejar imágenes.
HtmlInputCheckBox :
se corresponde con la etiqueta <input type=checkbox>, y gracias a el tenemos acceso en el servidor a este tipo
de elemento
Para determinar si se selecciona el control, utilice la propiedad Checked.
HtmlInputRadioButton :
El control HTML que es instancia de esta clase generará en el cliente una etiqueta <input type=radio>,
permitiendo al código de servidor interactuar con este elemento.
No tiene funcionalidad integrada para mostrar un título para el botón de opción
Para determinar si el control HtmlInputRadioButton está seleccionado, pruebe la propiedad Checked.
HtmlInputText:
Se corresponde con las etiquetas <input type=text> y <input type=password>. El tipo de caja de texto que se
genera viene dado por el valor de la propiedad type. Este control ya lo hemos visto en acción en varios
ejemplos.
HtmlSelect:
50
Este control HTML se corresponde con una lista desplegable del lenguaje HTML, es decir, con una etiqueta
<select>.
HtmlTable :
Este control se corresponde con una tabla del lenguaje HTML, es decir, permite el acceso desde el código de
servidor a una etiqueta <table>.
Esta clase posee una colección llamada Rows, que contiene objetos de la clase HtmlTableRow.
Propiedades:
Border:Use la propiedad Border para especificar el ancho del borde (en píxeles).
BgColor:Obtiene o establece el color de fondo
CellPadding:Obtiene o establece la cantidad de espacio entre el contenido de una celda y el borde de la
misma
CellSpacing:Obtiene o establece la cantidad de espacio (en píxeles) entre las celdas adyacentes
HtmlTableRow
Clase relacionada con la anterior, es el control HTML que permite manipular una fila de una tabla. Esta clase
posee una colección llamada Cells, que contiene objetos de la clase HtmlTableCell.
HtmlTableCell
Clase que permite el acceso a las celdas de una tabla, es decir, se corresponde con las etiquetas <td> y <th>.
CONTOLES WEB DE SERVIDOR
Los controles Web ofrecen un mayor nivel de abstracción que los controles HTML, y su modelo de objetos no
refleja la sintaxis HTML necesariamente. Cuando la página se carga en el navegador, el control Web
determina el tipo de navegador que ha realizado la petición, y de acuerdo con esta información genera el
código HTML apropiado, podemos decir que en este aspecto se trata de controles inteligentes.
Son similares a los controles HTML de servidor. Se generan en el servidor y permiten crear interfaces de
usuario complejas con facilidad. Necesitan el atributo runat=server. No necesariamente se relacionan con
elementos HTML y pueden representar elementos más complejos de la interfaz de usuario. Por ejemplo, el
control web Calendar.
Para crear un control web, utilizar la siguiente sintaxis:
<asp:Control id=nombre runat=server>
La clase de base System.Web.UI.WebControls.WebControl contiene todas las propiedades comunes. La
mayoría de los controles Web de servidor derivan de esta clase.
Para usar un control Web de servidor, use la sintaxis siguiente (que usa el control TextBox como ejemplo):
<asp:textbox text="hello world" runat=server />
51
Los controles Web básicos proporcionan la misma funcionalidad que sus correspondientes controles HTML
de servidor. Sin embargo, los controles Web básicos incluyen métodos, eventos y propiedades adicionales que
puede usar par programar.
Tres tipos de controles Web:
controles Web intrínsecos (que son los equivalentes a los controles HTML), controles Web de lista,
controles Web ricos
controles Web de validación
Los beneficios que se desprenden de utilizar controles Web intrínsecos sobre los controles HTML vistos
anteriormente son:
Se ofrece una convención de nomenclatura para controles similares.
Existen propiedades comunes para todos los controles, ofreciéndose un modelo de objetos más robusto.
Se incluyen propiedades específicas de los controles.
Se genera código HTML específico para cada navegador Web.
Similitud con Controles HTML
Al igual que sucedía con los controles HTML, para permitir hacer referencia a los controles dentro del código
fuente de la página, se debe utilizar el atributo id.
Diferencias con Controles HTML
Al declarar los controles.
Algunos nombres de las propiedades cambian
En los métodos para el tratamiento de eventos de la pulsación de un botón del ratón en los controles HTML
utilizamos la propiedad onserverclick, y en los controles Web utilizamos la propiedad onclick.
Button:
Este control Web representa un botón, se corresponde con la etiqueta <input type=submit>, es decir, un botón
que envía el contenido de un formulario al servidor.
Esta clase se corresponde con el control Web <asp:Button>
CheckBox :
Control Web que se corresponde con una etiqueta <input type=checkbox> del lenguaje HTML.
Propiedad AutoPostBack:establece un valor que indica si el estado del control CheckBos se devuelve
automáticamente al servidor cuando se hace clic en él.
CheckBoxList
52
Este control permite utilizar una lista de selección múltiple de elementos checkbox.
Este objeto posee una colección Items que contiene todos los objetos CheckBox.
Se puede especificar a través de las propiedades RepeatDirection y RepeatLayout la distribución de los
CheckBox en la página.
DropDownList :
Este control Web representa una lista desplegable, y se corresponde con la etiqueta <select> de HTML
PostBack
Cada uno de los elementos del control DropDownList se indica con un objeto de la clase ListItem.
HyperLink
Este otro control Web representa un enlace en la página, por lo tanto generará en el cliente una etiqueta <a>.
Image
Control Web que representa una imagen dentro de una página ASP .NET, generará como resultado de su
ejecución una etiqueta <img> de HTML. Para indicar la imagen que deseamos mostrar se utilizará la
propiedad ImageURL.
ImageButton
Este control es muy similar al anterior, pero además de mostrar una imagen posee la característica adicional
de funcionar como un botón de tipo submit, es decir, al pulsar el botón se envían los contenidos del formulario
al servidor. Este control generan en el cliente la etiqueta HTML <input type=image>.
LinkButton
Este control va a representar un botón que presenta un estilo similar a los enlaces, el control LinkButton
presenta una apariencia similar a un control Hyperlink, pero sin embargo ofrece la misma funcionalidad que
un control Button, es decir, presenta un texto a modo de enlace que al pulsarlo enviará el formulario en el que
se encuentre al servidor.
ListBox
Este nuevo control Web representa una lista de selección sencilla o múltiple, es similar al control
DropDownList, pero en este caso se muestran varios elementos de la lista y se permite la selección múltiple.
Este control Web también se corresponde con una etiqueta <select> en el código HTML
Rows:indicamos el número de filas visibles
SelectionMode: indicamos si se permite la selección múltiple, mediante el valor Multiple, o bien la selección
simple mediante el valor Single.
Panel
Este otro control Web intrínseco se utiliza para agrupar controles y realizar la función de contenedor de los
53
mismos. El control Panel posee una propiedad llamada Controls que es una colección que contiene todos los
controles incluidos dentro del objeto Panel.
PlaceHolder
Control Web que realiza también la función de un contenedor de controles Web, pero en este caso no genera
ningún código HTML, se utiliza para añadir controles Web de forma dinámica en la página ASP .NET en un
punto determinado, para ello se utiliza su propiedad Controls.
RadioButton
Este control representa un botón de opción que se corresponde con el elemento <input type=radio> de HTML.
Muestra la misma funcionalidad, es decir, permite seleccionar una opción dentro de un mismo grupo de
opciones. Las opciones se agrupan mediante la propiedad GroupName .
RadioButtonList
Este control permite utilizar una lista de selección múltiple de controles RadioButton. Este objeto posee una
colección Items que contiene todos los objetos RadioButton. Se puede especificar a través de las propiedades
RepeatDirection y RepeatLayout la distribución de los RadioButton en la página, como se puede apreciar es
muy similar al control CheckBoxList, pero en este caso se utilizan controles RadioButton.
Table, TableRow y TableCell
Estos controles Web se encuentran muy relacionados entre sí, mediante la utilización de todos ellos podremos
generar tablas en HTML.
El control Web Table se corresponde con una tabla del lenguaje HTML, es decir, permite generar tablas del
lenguaje HTML. Esta clase posee una colección llamada Rows, que contiene objetos de la clase TableRow.
Aplicando estilos a los controles
Los controles Web ofrecen un completo soporte para las hojas de estilo, es decir, podemos aplicar los estilos
de forma similar a como lo hacemos en HTML para personalizar el aspecto de nuestros controles.
Tres formas de aplicar estilos:
Mediante propiedades:
Es mediante la propiedad CssClass
Mediante la propiedad Style: Es una colección que nos permite asignar valores a las distintas propiedades del
estilo del control.
<%@ Page Language="VB" %>
<script runat="server">
Sub Enviar(obj as object, e as eventargs)
Dim strIngreso As String = lbIngreso.SelectedItem.Text
54
Dim strEdad As String = rlEdad.SelectedItem.Text
lblMensaje.Text = "¡Hola, " & tbNombre.Text & "!<p>" & _
"Su ingreso es de: " & strIngreso & "<br>" & _
"Su edad es: " & strEdad & "<br>"
If rlEdad.SelectedIndex < 3 Then
lblMensaje.Text += "¡Eres joven!<p>"
Else
lblMensaje.Text += "¡Eres experimentado!<p>"
End If
If cbBoletin.Checked Then
lblMensaje.Text += "Pronto recibirá nuestro " & _
"boletín."
End If
End Sub
</script>
<html><body>
<form runat="server">
<asp:Label id="lblEncabezado" runat="server"
Height="25px" Width="100%" BackColor="#ddaa66"
ForeColor="white" Font−Bold="true"
Text="Un ejemplo de controles Web" />
<br>
<asp:Label id="lblMensaje" runat="server" /><p>
Teclee su nombre:
<asp:TextBox id="tbNombre" runat="server" /><p>
Seleccione su edad:<br>
55
<asp:RadioButtonList id="rlEdad" runat="server"
RepeatDirection="horizontal">
<asp:ListItem><18</asp:ListItem>
<asp:ListItem>19−24</asp:ListItem>
<asp:ListItem>25−34</asp:ListItem>
<asp:ListItem>35−49</asp:ListItem>
<asp:ListItem>50−65</asp:ListItem>
</asp:RadioButtonList><p>
Elija sus ingresos:<br>
<asp:ListBox id="lbIngreso" runat="server"
size=1>
<asp:ListItem>< 999€ al año</asp:ListItem>
<asp:ListItem>1000€−9999€</asp:ListItem>
<asp:ListItem>10000€−49999€</asp:ListItem>
<asp:ListItem>> 50000€</asp:ListItem>
</asp:ListBox><p>
¿Quiere recibir nuestro boletín?<br>
<asp:CheckBox id="cbBoletin" runat="server"
Text="¡Sí!" /><p>
<asp:Button id="btEnviar" runat="server"
Text="Enviar" OnClick="Enviar" />
</form>
</body></html>
Ver ejercicios/tema4/demografico/demograficoVB
EJERCICIO
Realizar ese mismo ejercicio con C#.
56
Solución: ejercicios/tema4/demografico/demograficoC
CÓMO ENVIAR DATOS INMEDIATAMENTE
Por ejemplo, imaginar un formulario que muestra las provincias de un país. Una vez seleccionada una
provincia, se envía el formulario, se realiza cierto procesamiento y se filtra la lista de ciudades de esa
provincia.
Se puede enviar datos inmediatamente con la propiedad AutoPostBack de los controles web. A true indica al
control que envíe los datos tan pronto como ocurra el evento.
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Drawing" %>
Se importa para poder usar el objeto Color.
<script runat="server">
Sub ControladorDeNombre(obj as object, e as eventargs)
lblMensaje.Text = tbNombre.Text & ", elija un color: "
end sub
Sub ControladorDeLista(obj as object, e as eventargs)
Dim strColor As String
Select Case obj.SelectedItem.Text
Case "Rojo": strColor = "red"
Case "Azul": strColor = "blue"
Case "Verde": strColor = "green"
Case "Blanco": strColor = "white"
End Select
El método Color.FromName crea un objeto Color de acuerdo al color indicado. Se puede utilizar este
objeto par establecer el color del listbox.
lbColor.BackColor = Color.FromName _
(strColor)
End Sub
</script>
57
<html><body>
<form runat="server">
Declaro un control web TextBox. Cuando ocurre el evento TextChanged se ejecuta el método
ControladorDeNombre porque la propiedad AutoPostBack está a trae.
<asp:TextBox id="tbNombre" runat="server"
OnTextChanged="ControladorDeNombre"
AutoPostBack="true" /><p>
<asp:Label id="lblMensaje" runat="server"
Text="Elija un color: " /><p>
<asp:ListBox id="lbColor" runat="server"
OnSelectedIndexChanged="ControladorDeLista"
AutoPostBack="true" > Lo mismo aquí.
<asp:Listitem>Rojo</asp:Listitem>
<asp:Listitem>Azul</asp:Listitem>
<asp:Listitem>Verde</asp:Listitem>
<asp:Listitem>Blanco</asp:Listitem>
</asp:ListBox>
</form>
</body></html>
Ver ejercicios/tema4/autopostback/ autopostbackVB
EJERCICIO:
Cuando se seleccione un item le da lista aparecerá una etiqueta informando cuál se ha seleccionado. Al
escribir un nombre en la caja de texto aparecerá en la etiqueta el nombre seguido de elige un color, al
elegir un color de la lista cambiará el color de la lista
58
59
Solución: Ejercicios/tema4/Autopostback/aaa
Debemos:
Utilizar elementos HTML regulares cuando no necesitemos controlarlos de forma programática. Por ejemplo,
no necesitamos manipular un vínculo, así que será mejor usar la etiqueta <a ref> en lugar de un control
HtmlAnchor o HyperLink.
Utilizar controles HTML de servidor cuando no deseemos invertir mucho tiempo en convertir páginas
existentes a formularios web.
Utilizar controles web de servidor cuando generemos formularios web que necesiten un acceso programado.
Con Asp net en distintas llamadas al formulario se mantiene el estado del mismo, es decir, se mantiene en la
lista el elemento seleccionado, sin que tengamos que escribir ningún código adicional, esto es posible gracias
al campo oculto que genera el Web Form y que se denomina _VIEWSTATE. Por lo tanto los Web Forms nos
permiten en distintas peticiones conservar los valores de los campos de los formularios.
60
EJERCICIOS:
• Genera una aplicación para elegir el nombre de un bebé. El usuario elegirá el sexo del bebé, y,
entonces, un listBox mostrará algunos nombres posibles. Cuando el usuario elija un nombre, se
mostrará un mensaje con el nombre elegido.
Solución: tema4−bebe
• Genera una página estándar para registrar usuarios con los siguientes campos: nombre (necesario),
fax y dirección de correo electrónico (necesario). Si falta alguno de los campos necesarios, muestra un
mensaje de error al usuario.
Solución: tema4−Registro
PREGUNTAS PARA ENTREGAR:
• ¿Cómo llevan un control del estado visual los formularios web?
• ¿Qué hace el saco de estado, y cómo se puede acceder a él?
• Verdadero o falso: Los eventos de los formularios Web se procesan antes que el evento Page_Load.
• ¿Cuál es la lista de parámetros estándar de un evento?
• ¿Cuál es la importancia de la etiqueta runat=server?
• ¿Para qué deberías utilizar controles HTML del servidor?
• ¿Cuál es el error en la siguiente sección de código?
<asp:Button id=btEnviar Clic=ControlaEsto>
• ¿Qué propiedad puedes utilizar para enviar código inmediatamente al servidor al ocurrir un evento?
• ¿Cuándo deberías utilizar controles Web en lugar de controles HTML de servidor?
TEMA 5: UN POCO MÁS DE FORMULARIOS WEB
CONTROLES DE USUARIO
Permiten guardar y reutilizar la funcionalidad que se desee de la interfaz de usuario.
Esquema típico: un formulario de inicio de sesión. Suelen tener dos cajas de texto (usuario y contraseña) y un
botón Enviar. Podemos crear un control de usuario que realice la misma tarea.
COMO GENERAR CONTROLES DE USUARIO
Un control de usuario es un archivo ASP.NET con una extensión .ascx. Contiene elementos de la interfaz de
usuario y código para controlarlos. Las diferencia es que los controles de usuario están integrados en otras
páginas en lugar de ser independientes. El siguiente listado lo guardaríamos con extensión ascx. Sería un
típico inicio de sesión. No contiene las etiquetas <html>,<form> o <body>.
<%=colorFondo%> es un bloque proveedor de código. Establece el color de fondo recogiéndolo de la variable
colorFondo. No podemos visualizarlo si no lo colocamos en una página asp.net.
<table style="background−color:<%=colorFondo%>;font: 10pt
verdana;border−width:1;border−style:solid;border−color:black;" cellspacing=15>
<tr>
61
<td><b>Inicio de sesión: </b></td>
<td><ASP:TextBox id="Usuario" runat="server"/></td>
</tr>
<tr>
<td><b>Contraseña: </b></td>
<td><ASP:TextBox id="Contr" TextMode="password" runat="server"/></td>
</tr>
<tr>
<td></td>
<td><ASP:Button Text="Enviar" runat="server" OnClick="Enviar" /></td>
</tr>
</tabla>
<p>
<ASP:Label id="lblMensaje" runat="server"/>
Vamos a ver la página asp.net en la que se basa el control de usuario.
<%@ Page Language="C#" %>
<script runat="server">
string nombreUsuario;
string contrasenia;
string colorFondo;
Public void Enviar(Object obj, Eventargs e)
{
lblMensaje.Text = "nombreUsuario: <b>" + Usuario.Text +
"</b><br>" +"contrasenia: <b>" + Contr.Text + "</b><p>";
}
</script>
62
<html><body>
<form runat="server">
<table style="background−color:<%=colorFondo%>;
font: 10pt verdana;border−width:1;
border−style:solid;border−color:black;"
cellspacing=15>
<tr>
<td><b>Inicio de sesión: </b></td>
<td><ASP:TextBox id="Usuario" runat="server"/></td>
</tr>
<tr>
<td><b>Contraseña: </b></td>
<td><ASP:TextBox id="Contr" TextMode="password"
runat="server"/></td>
</tr>
<tr>
<td></td>
<td><ASP:Button Text="Enviar" runat="server"
OnClick="Enviar" /></td>
</tr>
</table>
<p>
<ASP:Label id="lblMensaje" runat="server"/>
</form>
</body></html>
Ver tema5−inicio(no está en block de notas)
63
Declaro las variables nombreUsuario, contrasenia y colorFondo, y método enviar.
Hay 3 pasos para convertir una página ASP.NET en control de usuario.
• Quitar las etiquetas <html>,<form> y <body>.
• Modificar el archivo para que tenga extensión ascx.
• Cambiar la directiva Page por Control.
<%@ Page Language=C# %> sería <%@ Control Language=C# %>
La declaración del código del control de usuario sería:
<script runat="server" language="c#">
public string nombreUsuario;
public string contrasenia;
public string colorFondo="White";
public void Enviar(Object obj, EventArgs e)
{
lblMensaje.Text = "nombreUsuario: <b>" + Usuario.Text +
"</b><br>" +"contrasenia: <b>" + Contr.Text + "</b><p>";
}
</script>
<table style="background−color:<%=colorFondo%>;
font: 10pt verdana;border−width:1;
border−style:solid;border−color:black;"
cellspacing=15>
<tr>
<td><b>Inicio de sesión: </b></td>
<td><ASP:TextBox id="Usuario" runat="server"/></td>
</tr>
<tr>
<td><b>Contraseña: </b></td>
64
<td><ASP:TextBox id="Contr" TextMode="password"
runat="server"/></td>
</tr>
<tr>
<td></td>
<td><ASP:Button Text="Enviar" runat="server"
OnClick="Enviar" ID="Button1"/></td>
</tr>
</table>
<p>
<ASP:Label id="lblMensaje" runat="server"/>v
COMO UTILIZAR CONTROLES DE USUARIO
Se utilizan como cualquier otro control. Creando una instancia en la porción de la interfaz de la página. Para
colocar controles de usuario en otras páginas asp.net, primero hay que registrarlos con la directiva @Register
Al registrar un control le decimos a asp.net que queremos extender el formulario web con un control de
servidor nuevo. Se hace con el propósito de que la página tenga una ruta válida y un nombre definido para
utilizar el control:
<%@ Register TagPrefix=Prefijo TagName=nombreControl src=rutaDelArchivo Namespace=Nombre
%>
El atributo TagPrefix define al grupo al que pertenece el control. Puede tener el TagPrefix que yo quiera.
La propiedad TagName da al control un nombre.
La propiedad src indica el lugar de origen del control de usuario.
El atributo Namespace es un elemento opcional que establece un espacio de nombre que se asociará con el
TagPrefix. Esto sirve para agrupar y clasificar posteriormente los controles de usuario.
<%@ Page Language="VB" %>
<%@ Register TagPrefix="AASPNET" TagName="inicioSesion" src="inicioSesion.ascx" %>
<script runat="server">
Sub Page_Load(obj as object, e as eventargs)
lblMensaje.Text = "Propiedades del control " & _
65
"de usuario:<br> " & _
"identificador: " & inicioSesion1.id & "<br>" & _
"colorFondo: " & inicioSesion1.colorFondo & "<br>" & _
"nombreUsuario: " & inicioSesion1.nombreUsuario & "<br>" & _
"contrasenia: " & inicioSesion1.contrasenia
end sub
</script>
<html><body>
<form runat="server">
<AASPNET:inicioSesion id="inicioSesion1" runat="server"
contrasenia="MiContrasenia"
nombreUsuario="David"
colorFondo="Beige" />
</form>
<p>
<asp:Label id="lblMensaje" runat="server" />
<p>
</body></html>
<%@ Page Language="C#" %>
<%@ Register TagPrefix="AASPNET" TagName="inicioSesion" src="inicioSesion.ascx" %>
Establece su prefijo como AASPNET y su nombre de control en inicioSesion
<script runat="server">
public void Page_Load(Object obj, EventArgs e)
{
lblMensaje.Text = "Propiedades del control de usuario:<br> " +
"colorFondo: " + inicioSesion1.colorFondo + "<br>" +
66
"nombreUsuario: " + inicioSesion1.nombreUsuario + "<br>" +
"contrasenia: " + inicioSesion1.contrasenia;
}
Muestra las propiedades del control en la etiqueta.
</script>
<html><body>
<form runat="server">
Son las propiedades públicas del control
<AASPNET:inicioSesion id="inicioSesion1" runat="server"
contrasenia="MiContrasenia"
nombreUsuario="David"
colorFondo="Beige" />
</form>
<p>
<asp:Label id="lblMensaje" runat="server" />
<p>
</body></html> Ver tema5−EjemploUserControl
CONTROLES PERSONALIZADOS
No son controles de usuario. En lugar de encapsular cierta funcionalidad de la interfaz del usuario, pueden
definir su comportamiento totalmente original. Por ejemplo, ASP.NET no ofrece un control integrado para
interpretar dibujos monocromáticos. Un desarrollador podría generar un control personalizado para ofrecer
esta funcionalidad. Los controles de usuario se utilizan cuando se desea combinar la funcionalidad de
controles existentes, los controles personalizados se utilizan cuando ninguno de los controles existentes
cumple con sus necesidades.
Todos los objetos en el marco de trabajo de los formularios Web se derivan directa o indirectamente de la
clase System.Web.UI.Control.
Se puede insertar un control personalizado en cualquier parte de esta jerarquía, siempre y cuando derive de
alguna manera de la clase Control.
EJERCICIOS:
Generar un planificador de juntas. Deberá incluir un calendario, un cuadro de texto para capturas del
67
usuario y una etiqueta que muestre los datos en curso. Utilizar AutoPostBack y el evento TextChanged
cuando el usuario teclee notas en el cuadro de texto. Almacenar dichas notas en variables de sesión de
modo que el usuario pueda verlas posteriormente. Cuando se agregue una nota, generar
dinámicamente una etiqueta para recibir alguna reacción. Será un control .ascx y se incluirá en una
página .aspx
Solución tema5/ Tema5Ej
PREGUNTAS PARA ENTREGAR:
• Verdadero o falso: Un control de usuario puede utilizarse de manera independiente.
• ¿Cuáles son los tres requerimientos para convertir un archivo .aspx en control de usuario?
TEMA 6: VALIDACIÓN DE LAS PÁGINAS ASP.NET
ESQUEMAS DE VALIDACIÓN
La validación de lo que captura el usuario en los formularios es una de las tareas más importantes para los
desarrolladores.
Una situación típica donde se requiere validación:
La interfaz pide el nombre y apellidos, dirección de correo electrónico, domicilio, ciudad, estado, código
postal y número de teléfono del usuario.
<html><body>
<form runat="server">
<asp:Label id="lblEncabezado" runat="server"
Height="25px" Width="100%" BackColor="#ddaa66"
ForeColor="white" Font−Bold="true"
Text="Un ejemplo de validación" />
<asp:Label id="lblMensaje" runat="server" /><br>
<asp:Panel id="Panel1" runat="server">
<table>
<tr>
<td width="100" valign="top">
Nombre y apellidos:
</td>
<td width="300" valign="top">
68
<asp:TextBox id="tbNombre" runat="server" />
<asp:TextBox id="tbApellidos" runat="server" />
</td>
</tr>
<tr>
<td valign="top">Correo electrónico:</td>
<td valign="top">
<asp:TextBox id="tbCorreoE"
runat="server" />
</td>
</tr>
<tr>
<td valign="top">Domicilio:</td>
<td valign="top">
<asp:TextBox id="tbDomicilio"
runat="server" />
</td>
</tr>
<tr>
<td valign="top">Ciudad, Estado y Código postal:</td>
<td valign="top">
<asp:TextBox id="tbCiudad"
runat="server" />,
<asp:TextBox id="tbEstado" runat="server"
size=2 /> 
<asp:TextBox id="tbCodigoPostal" runat="server"
69
size=5 />
</td>
</tr>
<tr>
<td valign="top">Teléfono:</td>
<td valign="top">
<asp:TextBox id="tbTelefono" runat="server"
size=11 /><p>
</td>
</tr>
<tr>
<td colspan="2" valign="top" align="right">
<asp:Button id="btEnviar" runat="server"
text="Agregar" />
</td>
</tr>
</table>
</asp:Panel>
</form>
</body></html>
70
Se puede validar la captura de usuario con instrucciones if. Después de verificar todo lo capturado de esta
forma, se puede tomar dos rutas. Si todo está en el formato correcto, se puede insertar en una base de datos. Si
alguno de los datos no es correcto, hay que avisar al usuario dónde está el error y permitirle corregirlo antes
de insertar los datos.
VALIDACIÓN EN ASP.NET
Permiten validar con facilidad cualquier dato que se haya capturado en un formulario Web.
Admiten validaciones como campos necesarios, comparación de patrones o validaciones personalizadas.
Permiten personalizar los mensajes de error.
El trabajo de un control de validación es vigilar otro control de servidor y validar su contenido.
Un mismo control puede tener distintos tipos de validación, es decir, se pueden utilizar distintos controles de
validación sobre un mismo control a validar.
71
Los controles de validación funcionan en el cliente y en el servidor.
Valida primero en el cliente, Asp no permite que un formulario sea enviado si tiene información inválida.
Valida de nuevo en el servidor respecto a los recursos no disponibles en el cliente, como ejemplo una B.D.
Propiedades importantes:
ControlToValidate: Control a validar.
ErrorMessage: Mensaje de error que sacará.
IsValid: indica si la validación es correcta, también se puede hacer a nivel de página.
TIPOS DE CONTROLES DE VALIDACIÓN EN ASP.NET
RequiredFieldValidator
Se utiliza para verificar que se ha dado algún valor a un campo, es decir, valida que se ha asignado un valor a
un campo requerido de un Web Form.
CompareValidator
Este control Web de validación lo utilizaremos para comparar el valor que contiene un control Web con un
valor específico, que puede ser un valor determinado especificado como una constante o bien un valor de otro
control Web.
Este control Web se utilizará con un operador de comparación, y presenta las siguientes propiedades
adicionales:
ValueToCompare: esta propiedad se utilizará cuando deseemos comparar el valor de un control Web con un
valor constante, esta propiedad es la que contendrá este valor constante.
ControlToCompare: esta propiedad se utilizará cuando deseemos compara el valor de un control Web con
otro, esta propiedad contendrá el identificador del otro control contra el que se quiere comparar el control
Web en cuestión.
Type: indica el tipo de dato de los valores que se van a comparar, esta propiedad puede presentar los
siguientes valores, Currency, Date, Double, Integer y String, que se corresponden con los distintos tipos de
datos que podemos indicar.
Operator: esta última propiedad va a contener el tipo de operador que se va a utilizar en la comparación de
los dos valores. Esta propiedad puede tener los siguientes valores,Equal(igual)GreaterThan(mayor),
GreaterThanEqual (mayor o igual), LessThan (menor), LessThanEqual (menor o igual ), NotEqual (distinto) y
DataTypeCheck (validación de tipo).
El operador DataTypeCheck es utilizado para validar el tipo de datos del control Web, en este caso no se
compara con otro control, sino que únicamente se comprueba el tipo del valor del control.
RangeValidator
Este control Web se utilizará cuando sea necesario comprobar si un valor de entrada de un control Web se
72
encuentra comprendido en un rango determinado.
El control RangeValidator ofrece tres propiedades adicionales para llevar a cabo su labor de validación, las
propiedades son las siguientes:
MinimumControl: esta propiedad define el valor mínimo del rango permitido para el control.
MaximumControl: esta propiedad define el valor máximo
Type: indica el tipo de dato que se utiliza para comparar los valores dentro del rango especificado, esta
propiedad puede tener los siguientes valores, Currency, Date, Double, Integer y String.
RegularExpressionValidator
Este otro control Web de validación es utilizado para comparar el valor del control correspondiente con una
expresión regular.
Este control debe hacer uso de la propiedad ValidationExpression para indicar la expresión regular con la que
se va a comparar el valor indicado en el control Web que se desea validar.
ValidationSummary
Este control difiere del resto, ya que en realidad no va a realizar un tipo de validación determinada, sino que
contiene todos los mensajes de error que se han producido y muestra una lista de ellos en la página, en el caso
de que la página no sea válida, es decir, algunas de las validaciones han fallado.
Este control mostrará todos los mensajes indicados en la propiedad ErrorMessage de cada uno de los controles
de validación cuya validación ha fallado en la página. Así en este caso los controles de validación no
mostrarán el mensaje de error de la propiedad ErrorMessage, sino que mostrarán si procede el texto incluido
entre sus etiquetas de inicio y fin.
Propiedades:
HeaderText: esta propiedad contendrá el texto que va a mostrarse como cabecera a modo de descripción de
los errores.
ShowSummary: esta propiedad, que puede tener los valores True/False, indicará si deseamos mostrar o no el
resumen de validación de la página ASP .NET. DisplayMode: en esta propiedad podemos indicar la forma en
la que se mostrarán las distintas descripciones de cada uno de los errores de validación encontrados en la
página, puede presentar los siguientes valores, BulletList (una lista con puntos), List (una lista) y
SingleParagraph (en un único párrafo).
CustomValidator
Este último control Web de validación se utilizará para realizar una validación personalizada, este control
llamará a una función definida por el usuario que será la que realice la validación. Esta función puede estar
definida en el cliente o bien en el servidor.
Propiedades destacadas:
ClientValidationFunction: en esta propiedad indicaremos el nombre de la función del lado del cliente que
realizará la validación deseada, en este caso la función será una función definida en un lenguaje de script de
73
cliente , como puede ser JavaScript, y que sea soportado por el navegador.
OnServerValidate: en esta propiedad debemos indicar el nombre de la función de servidor que se va a
encargar de realizar la validación correspondiente, esta función se ejecutará cuando se produzca el evento
ServerValidate, es decir, esta propiedad va a ser el manejador del evento que se produce cuando se realiza la
validación en el servidor.
La función de validación va a recibir dos parámetros:
Uno de la clase Object, que representa al control de la clase CustomValidator.
Otro objeto de la clase ServerValidateEventArgs, que se va a utilizar para indicar si la validación ha sido
correcta o no. El objeto de clase ServerValidateEventArgs posee la propiedad Value para obtener el valor del
control que se desea validar y la propiedad IsValid, en la que se indicará el resultado de la validación.
Los controles que se pueden validar son:
HtmlInputText
HtmlTextArea
HtmlSelect
HtmlInputFile
TextBox
ListBox
DropDownList
RadioButtonList
COMO FUNCIONAN LOS CONTROLES DE VALIDACIÓN
Para generar un control Validation en una página ASP.net hay que agregar la etiqueta adecuada de validación
al formulario Web.
Los controles de validación funcionan tanto en el cliente como en el servidor. Cuando un usuario teclea datos
en un control Web que infrinjan la regla de validación que hayamos especificado, el usuario será alertado de
inmediato. Asp.net no permite que un formulario sea enviado si la información no es válida. Esto significa que
no hay que enviar el formulario al servidor para hacer la validación, y que ésta se realiza en el cliente
automáticamente. (La validación en el cliente sólo es posible en exploradores web que soporten DHTML y
JavaScript).
Cuando el formulario se envía por fin al servidor, asp.net vuelve a validad las capturas. Esto permite volver a
verificar los datos respecto a los recursos que no hayan estado disponibles en el cliente, como una base de
datos.
Ejemplo sencillo de validación:
<%@ Page Language="VB" %>
74
<script runat="server">
Sub Enviar(obj as object, e as eventargs)
If Page.IsValid then
lblMensaje.Text = "¡Ha pasado la validación!"
End If
End Sub
</script>
<html><body>
<form runat="server">
<asp:Label id="lblMensaje" runat="server" /><p>
Teclee su nombre:
<asp:TextBox id="tbNombre" runat="server" /><br>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="tbNombre"
ErrorMessage="Se necesita su nombre."/><p>
<asp:Button id="tbEnviar" runat="server"
Text="Enviar"
OnClick="Enviar" />
</form>
</body></html>
Ver tema6−sencilloVB.aspx
<%@ Page Language="C#" %>
<script runat="server">
void Enviar(Object sender, EventArgs e)
{
if (Page.IsValid)
75
{
lblMensaje.Text = "¡Ha pasado la validación!";
}
}
</script>
<html><body>
<form runat="server">
<asp:Label id="lblMensaje" runat="server" /><p>
Teclee su nombre:
<asp:TextBox id="tbNombre" runat="server" /><br>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="tbNombre"
ErrorMessage="Se necesita su nombre."/><p>
<asp:Button id="tbEnviar" runat="server"
Text="Enviar"
OnClick="Enviar" />
</form>
</body></html>
La propiedad ControlToValidate establece a qué control debe vigilar este validador (a tbNombre en este
caso).
Si captura cualquier dato en el cuadro de tbNobmre, se cumple RequiredFieldValidator. Este control verifica
si un campo contiene datos. Todo control de validación contiene una propiedad IsValid que indica si la
validación es correcta.
Cuando el formulario se envía se ejecuta el método Enviar. La propiedad Page.IsValid garantiza que se
cumplan todos los controles de validación de la página. También se podría verificar la propiedad IsValid de
cada control.
Hacer la prueba haciendo saltar el mensaje de error y escribiendo algo en la caja de texto y pulsando fuera sin
enviar. El mensaje de error desaparece porque se valida al perder el foco.
USO DE LOS CONTROLES DE VALIDACIÓN
76
Todos los controles de validación comparten propiedades similares. Dos propiedades, (sin incluir a
runat=server).
ControlToValide: establece el nombre del control de servidor que deberá ser vigilado por este validador.
ErrorMessage que indica a asp.net el mensaje por mostrar al usuario si falla la validación.
Veamos que tipos de validación se necesitan aquí:
<html><body>
<form runat="server">
<asp:Label id="lblEncabezado" runat="server"
Height="25px" Width="100%" BackColor="#ddaa66"
ForeColor="white" Font−Bold="true"
Text="Un ejemplo de validación" />
<asp:Label id="lblMensaje" runat="server" /><br>
<asp:Panel id="Panel1" runat="server">
<table>
<tr>
<td width="100" valign="top">
Nombre y apellidos:
</td>
<td width="300" valign="top">
<asp:TextBox id="tbNombre" runat="server" />
<asp:TextBox id="tbApellidos" runat="server" />
</td>
</tr>
<tr>
<td valign="top">Correo electrónico:</td>
<td valign="top">
<asp:TextBox id="tbCorreoE"
77
runat="server" />
</td>
</tr>
<tr>
<td valign="top">Domicilio:</td>
<td valign="top">
<asp:TextBox id="tbDomicilio"
runat="server" />
</td>
</tr>
<tr>
<td valign="top">Ciudad, Estado y Código postal:</td>
<td valign="top">
<asp:TextBox id="tbCiudad"
runat="server" />,
<asp:TextBox id="tbEstado" runat="server"
size=2 /> 
<asp:TextBox id="tbCodigoPostal" runat="server"
size=5 />
</td>
</tr>
<tr>
<td valign="top">Teléfono:</td>
<td valign="top">
<asp:TextBox id="tbTelefono" runat="server"
size=11 /><p>
78
</td>
</tr>
<tr>
<td colspan="2" valign="top" align="right">
<asp:Button id="btEnviar" runat="server"
text="Agregar" />
</td>
</tr>
</table>
</asp:Panel>
</form>
</body></html>
79
Para sus cuadros de texto nombre y apellido que se teclee algo, siempre y cuando sea texto. Esta validación
requiere el control RequiredFieldValidator. Para mayor seguridad también podemos comprobar que no sean
iguales. Con CompareValidator.
En el cuadro del correo electrónico nos tendremos que asegurar que la dirección tenga un formato adecuado,
como [email protected]. El control RegularExpressionValidator realiza esta función.
Demos por hecho que queremos permitir sólo usuarios de cierto lugar (un rango de códigos postales) para
enviar su formulario. Este tipo de validación se hace con RangeValidator.
El mismo código mejorado:
<html><body>
<form runat="server">
<asp:Label id="lblEncabezado" runat="server"
80
Height="25px" Width="100%" BackColor="#ddaa66"
ForeColor="white" Font−Bold="true"
Text="Un ejemplo de validación" />
<asp:Label id="lblMensaje" runat="server" /><br>
<asp:Panel id="Panel1" runat="server">
<table>
<tr>
<td width="100" valign="top">
Nombre y apellidos:
</td>
<td width="300" valign="top">
<asp:TextBox id="tbNombre" runat="server" />
<asp:TextBox id="tbApellidos" runat="server" />
<br>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="tbNombre"
ErrorMessage="Se necesita el nombre"/>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="tbApellidos"
ErrorMessage="Se necesitan los apellidos"/>
<asp:CompareValidator runat="server"
ControlToValidate="tbNombre"
ControlToCompare="tbApellidos"
Type="String"
Operator="NotEqual"
ErrorMessage="El nombre y los apellidos no pueden ser iguales" />
81
</td>
</tr>
<tr>
<td valign="top">Correo electrónico (sólo .com):</td>
<td valign="top">
<asp:TextBox id="tbCorreoE"
runat="server" /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbCorreoE"
ValidationExpression="\w+\@\w+\.com"
ErrorMessage="No es un correo electrónico correcto"/>
</td>
</tr>
<tr>
<td valign="top">Domicilio:</td>
<td valign="top">
<asp:TextBox id="tbDomicilio"
runat="server" />
</td>
</tr>
<tr>
<td valign="top">Ciudad, Estado y Código postal (5 cifras):</td>
<td valign="top">
<asp:TextBox id="tbCiudad"
runat="server" />
82
<asp:TextBox id="tbEstado" runat="server"
size=2 /> 
<asp:TextBox id="tbZonaPostal" runat="server"
size=5 /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbZonaPostal"
ValidationExpression="[0−9]{5}"
ErrorMessage="No es una zona postal correcta" />
<br>
<asp:RangeValidator runat="server"
ControlToValidate="tbZonaPostal"
MinimumValue="00000" MaximumValue="22222"
Type="String"
ErrorMessage="No se encuentra en la región adecuada" />
</td>
</tr>
<tr>
<td valign="top">Teléfono (<i>xxxxx−xxxx</i>):</td>
<td valign="top">
<asp:TextBox id="tbTelefono" runat="server"
size=11 /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbTelefono"
ValidationExpression="[0−9]{5}−[0−9]{4}"
83
ErrorMessage="No es un número telefónico correcto"/>
</td>
</tr>
<tr>
<td colspan="2" valign="top" align="right">
<asp:Button id="btEnviar" runat="server"
text="Agregar" />
</td>
</tr>
</table>
</asp:Panel>
</form>
</body></html>
Los controles de correo electrónico, ciudad, estado, código postal y teléfono NO tienen sus correspondientes
RequiredFieldValidators, lo que los convierte en opcionales. Aún si el campo está vacío, la propiedad
IsValid devolverá true.
El formulario sólo acepta ciertos tipos de direcciones electrónicas (terminar en .com), códigos postales (5
números) y números de teléfono (9 números, con un guión entre el cuarto y el quinto).
Dos instancias de RequiredFieldValidators, aseguran que el usuario haya capturado algo en el nombre y
apellidos. Estos controles sólo tienen las dos propiedades necesarias, ControToValidate y ErrorMessage.
CompareValidator puede comparar el valor de un control de servidor con una constante, o con otro control
de servidor. La propiedad Type indica el tipo de valores que comparará, como String, Double.
Para comparar con un valor constante, en vez de ControlToCompare hay que usar ValueToCompare.
Si sólo se quiere verificar si lo capturado por el usuario es de un tipo de dato válido, se establece la propiedad
Operato de CompareValidator a DataTypeCheck y olvidarse de la propiedad ControlToCompare. En un
formulario Web todo lo capturado será una cadena, por lo que se podría no obtener una validación correcta.
Cuando tengamos dos o más controles Validation basados en un control de servidor, todas las condiciones
deberán cumplirse para dar por válida la captura.
El control RequierdFieldValidator considera inválido un campo en blanco. Todos los demás controles
aceptan campos vacíos.
COMO HACER VALIDACIONES EN EL SERVIDOR
84
Hay que controlar la validación en el servidor. La forma más sencilla de verificar el formulario es a través de
la propiedad IsValid del objeto Page. Si todos los datos verificados por los controles de validación son
satisfactorios, la propiedad tendrá valor true. Si cualquiera de ellos no lo es, será False.
<%@ Page Language="VB" %>
<script runat="server">
Sub Enviar (obj as object, e as eventargs)
If Page.IsValid then
lblMensaje.Text = "¡Correcto!"
Else
lblMensaje.Text = "Alguno de los campos no es válido."
End if
End sub
</script>
<html><body>
<form runat="server">
<asp:Label id="lblEncabezado" runat="server"
Height="25px" Width="100%" BackColor="#ddaa66"
ForeColor="white" Font−Bold="true"
Text="Un ejemplo de validación" />
<asp:Label id="lblMensaje" runat="server" /><br>
<asp:Panel id="Panel1" runat="server">
<table>
<tr>
<td width="100" valign="top">
Nombre y apellidos:
</td>
<td width="300" valign="top">
85
<asp:TextBox id="tbNombre" runat="server" />
<asp:TextBox id="tbApellidos" runat="server" />
<br>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="tbNombre"
ErrorMessage="Se necesita el nombre"/><br>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="tbApellidos"
ErrorMessage="Se necesitan los apellidos"/><br>
<asp:CompareValidator runat="server"
ControlToValidate="tbNombre"
ControlToCompare="tbApellidos"
Type="String"
Operator="NotEqual"
ErrorMessage="El nombre y los apellidos no pueden ser iguales" />
</td>
</tr>
<tr>
<td valign="top">Correo electrónico (sólo .com):</td>
<td valign="top">
<asp:TextBox id="tbCorreoE"
runat="server" /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbCorreoE"
ValidationExpression="\w+\@\w+\.com"
86
ErrorMessage="No es un correo electrónico correcto"
/>
</td>
</tr>
<tr>
<td valign="top">Domicilio:</td>
<td valign="top">
<asp:TextBox id="tbDomicilio"
runat="server" />
</td>
</tr>
<tr>
<td valign="top">Ciudad, Estado y Zona postal (5−digit):</td>
<td valign="top">
<asp:TextBox id="tbCiudad"
runat="server" />,
<asp:TextBox id="tbEstado" runat="server"
size=2 /> 
<asp:TextBox id="tbZonaPostal" runat="server"
size=5 /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbZonaPostal"
ValidationExpression="[0−9]{5}"
ErrorMessage="No es una zona postal correcta" />
<br>
87
<asp:RangeValidator runat="server"
ControlToValidate="tbZonaPostal"
MinimumValue="00000" MaximumValue="22222"
Type="String"
ErrorMessage="No se encuentra en la región adecuada" />
</td>
</tr>
<tr>
<td valign="top">Teléfono (<i>xxxx−xxxx</i>):</td>
<td valign="top">
<asp:TextBox id="tbTelefono" runat="server"
size=11 /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbTelefono"
ValidationExpression="[0−9]{4}−[0−9]{4}"
ErrorMessage="No es un número telefónico correcto"
/>
</td>
</tr>
<tr>
<td colspan="2" valign="top" align="right">
<asp:Button id="btEnviar" runat="server"
text="Agregar"
OnClick="Enviar" />
</td>
88
</tr>
</table>
</asp:Panel>
</form>
</body></html>
<%@ Page Language="c#" %>
<script runat="server">
Verifica si todos los controles Validation son válidos.
public void Enviar(Object obj , EventArgs e)
{
if (Page.IsValid)
{
lblMensaje.Text = "¡Correcto!";
}
else
{
lblMensaje.Text = "Alguno de los campos no es válido.";
}
}
</script>
<html><body>
<form runat="server">
<asp:Label id="lblEncabezado" runat="server"
Height="25px" Width="100%" BackColor="#ddaa66"
ForeColor="white" Font−Bold="true"
Text="Un ejemplo de validación" />
89
<asp:Label id="lblMensaje" runat="server" /><br>
<asp:Panel id="Panel1" runat="server">
<table>
<tr>
<td width="100" valign="top">
Nombre y apellidos:
</td>
<td width="300" valign="top">
<asp:TextBox id="tbNombre" runat="server" />
<asp:TextBox id="tbApellidos" runat="server" />
<br>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="tbNombre"
ErrorMessage="Se necesita el nombre"/><br>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="tbApellidos"
ErrorMessage="Se necesitan los apellidos"/><br>
<asp:CompareValidator runat="server"
ControlToValidate="tbNombre"
ControlToCompare="tbApellidos"
Type="String"
Operator="NotEqual"
ErrorMessage="El nombre y los apellidos no pueden ser iguales" />
</td>
</tr>
<tr>
90
<td valign="top">Correo electrónico (sólo .com):</td>
<td valign="top">
<asp:TextBox id="tbCorreoE"
runat="server" /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbCorreoE"
ValidationExpression="\w+\@\w+\.com"
ErrorMessage="No es un correo electrónico correcto"
/>
</td>
</tr>
<tr>
<td valign="top">Domicilio:</td>
<td valign="top">
<asp:TextBox id="tbDomicilio"
runat="server" />
</td>
</tr>
<tr>
<td valign="top">Ciudad, Estado y Zona postal (5−digit):</td>
<td valign="top">
<asp:TextBox id="tbCiudad"
runat="server" />,
<asp:TextBox id="tbEstado" runat="server"
size=2 /> 
91
<asp:TextBox id="tbZonaPostal" runat="server"
size=5 /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbZonaPostal"
ValidationExpression="[0−9]{5}"
ErrorMessage="No es una zona postal correcta" />
<br>
<asp:RangeValidator runat="server"
ControlToValidate="tbZonaPostal"
MinimumValue="00000" MaximumValue="22222"
Type="String"
ErrorMessage="No se encuentra en la región adecuada" />
</td>
</tr>
<tr>
<td valign="top">Teléfono (<i>xxxx−xxxx</i>):</td>
<td valign="top">
<asp:TextBox id="tbTelefono" runat="server"
size=11 /><br>
<asp:RegularExpressionValidator
runat="server"
ControlToValidate="tbTelefono"
ValidationExpression="[0−9]{4}−[0−9]{4}"
ErrorMessage="No es un número telefónico correcto"
/>
92
</td>
</tr>
<tr>
<td colspan="2" valign="top" align="right">
<asp:Button id="btEnviar" runat="server"
text="Agregar"
OnClick="Enviar" />
</td>
</tr>
</table>
</asp:Panel>
</form>
</body></html>
Ver tema6/ listado0706.aspx
La colección Validators contiene referencias a todos los controles. Puede iterar por esta colección para
determinar la validez de un control en particular:
public void Enviar(Object obj , EventArgs e)
{
if (Page.IsValid)
{
lblMensaje.Text = "¡Correcto!";
}
else
{
Ivalidator objValidator;
Foreach objValidator in Validators
{
93
lblMensaje.Text += objValidator.ErrorMessage;
}
}
}
También se puede verificar la propiedad IsValid de cualquier control mediante su nombre. Para ello hay que
asignar la propiedad id de cada control de validación. Por ejemplo, si el RegularExpressionValidator del
cuadro de texto del correo electrónico tuviera el id valCorreoE:
If (!valCorreoE.IsValid)
{
lblMensaje.Text+=valCorreoE.Message;
}
COMO INHABILITAR LA VALIDACIÓN
Con la propiedad Enabled a False:
<asp:RegularExpressionValidator runat=server ControlToValidate=tbCodigoPostal Enabled=False/>
También se puede inhabilitar toda la validación en el cliente estableciendo la propiedad clienttarget de la
directiva <% @ Page %> con un valor de downlevel:
<%@ Page Language=C# clienttarget=downlevel %>
Este comando hace que asp.net piense que está tratando con un explorador que no soporta DHTML, por lo
que no reconoce estos controles.
COMO PERSONALIZAR LA VALIDACIÓN
MENSAJES DE ERROR
Los controles de validación pueden colocarse en cualquier parte de la página. Por ejemplo, se pueden colocar
al principio de la página si se quiere agrupar los mensajes de error.
Con la propiedad Display en Dynamic el siguiente código muestra los RequiredFieldValidator de los campos
nombre y apellido como objetos desplegados de forma dinámica: Se agrupan los controles y se separan
cuando aparece un mensaje de error.
<asp: RequiredFieldValidator runat=server ControToValidate=tbNombre ErrorMessage=Se necesita un
nombre Display=dynamic/>
<asp: RequiredFieldValidator runat=server ControToValidate=tbApellidos ErrorMessage=Se necesita un
apellido Display=dynamic/>
<asp:CompareValidator runat=server ControlToValidate=tbNombre ControlToCompare=tbApellidos
94
Type=String Operator=NotEqual ErrorMessage=El nombre y los apellidos no pueden ser iguales
Display=dinamic/>
COMO MOSTRAR RESÚMENES DE VALIDACIÓN
Técnicamente, los mensajes de error se colocan donde se encuentre el control Validation en la página.
Podemos elegir dónde colocarlos:
Directo: en el mismo lugar donde se encuentre el control de validación de la página.
Resumen: en un resumen por separado (podría ser una ventana de aparición súbita en exploradores web que
usasn DHTML).
Tanto en directo como en resumen: los mensajes de error respectivos pueden ser distintos.
Donde se quiera.
El método es útil cuando queremos listar todos los mensajes de error en un lugar, como al principìo de la
página.
En lugar de colocar todos sus controles de validación en un lugar, podemos dejarlos donde estásn y valernos
del control ValidationSummary. Este control despliega los mensajes de error en un lugar de la página con un
formato especificado.
<asp:ValidationSummary runat=server DisplayMode=BulletList/>
Con la adición de la propiedad ShowMessageBox, puede generar un mensaje de aparición súbita con el
control VatidationSummary.
<asp:ValidationSummary runat=server ShowMessageBox=True DisplayMode=BulletList/>
Se puede establecer la propiedad Text de los controles de validación con cualquier etiqueta HTML válida. Por
lo que podemos mostrar imágenes en los mensajes de error.
CONTROLES DE VALIDACIÓN PERSONALIZADOS
Si ninguno de los controles de validación satisface nuestras necesidades con el control CustomValidator
podemos definir cualquier tipo de validación que se necesite. Hay que crear un procedimiento. Cuando el
usuario teclee datos el CustomValidator ejecutará el método que hayamos generado.
<%@ Page Language="VB" %>
<script runat="server">
Sub Enviar(obj as object, e as eventargs)
' Hacer algo
End Sub
Sub ValideEsto(obj as Object, args as _
95
ServerValidateEventArgs)
If Len(args.Value) < 8 Then
args.IsValid = False
Else
args.IsValid = True
End If
End Sub
</script>
<html><body>
<form runat="server">
<asp:Label id="lblMensaje" runat="server" />
<table>
<tr>
<td valign="top">Nombre de usuario:</td>
<td valign="top">
<asp:Textbox id="tbNombreUsuario" runat="server" />
<br>
<asp:CustomValidator runat="server"
OnServerValidate="ValideEsto"
Display="Dynamic"
ControlToValidate="tbNombreUsuario"
ErrorMessage="El nombre del usuario debe tener 8 o más caracteres."/>
</td>
</tr>
<tr>
<td valign="top">Contraseña:</td>
96
<td valign="top">
<asp:Textbox id="tbContrasenia" runat="server"
TextMode="password" />
</td>
</tr>
<tr>
<td align="right" colspan="2">
<ASP:Button id="tbEnviar" runat="server"
OnClick="Enviar"
Text="Enviar" />
</td>
</tr>
</table>
</form>
</body></html>
<%@ Page Language="c#" %>
<script runat="server">
public void (Object obj, EventArgs e)
{
// Hacer algo;
}
args contiene todo lo capturado por el usuario. Uliliza la propiedad value para recuperar el texto contenido en
este objeto y la propiedad IsValid para establecer la validez del control.
public void ValideEsto(Object obj, ServerValidateEventArgs args)
{
if(Len(args.Value) < 8)
args.IsValid = False;
97
else
args.IsValid = True;
}
</script>
<html><body>
<form runat="server">
<asp:Label id="lblMensaje" runat="server" />
<table>
<tr>
<td valign="top">Nombre de usuario:</td>
<td valign="top">
<asp:Textbox id="tbNombreUsuario" runat="server" />
<br>
OnServerValidate se procesa el primero.
<asp:CustomValidator runat="server"
OnServerValidate="ValideEsto"
Display="Dynamic"
ControlToValidate="tbNombreUsuario"
ErrorMessage="El nombre del usuario debe tener 8 o más caracteres."/>
</td>
</tr>
<tr>
<td valign="top">Contraseña:</td>
<td valign="top">
<asp:Textbox id="tbContrasenia" runat="server"
TextMode="password" />
98
</td>
</tr>
<tr>
<td align="right" colspan="2">
<ASP:Button id="tbEnviar" runat="server"
OnClick="Enviar"
Text="Enviar" />
</td>
</tr>
</table>
</form>
</body></html>
CustomValidator también permite validar en el cliente. Hay que generar un controlador de eventos en
JavaScrip:
<script language=JavaScript>
function validarLongitud (oSrc,txtValue)
{
var retValot=true; //asume que todo está bien
if(txtValor.length<8)
{
retValor=false;
}
return retValor;
}
</script>
Luego el control CustomValidator deberá establecer la propiedad OnClientSideValidate hacia el método de
JavaScript.
99
<asp:CustomValidator runat="server" OnServerValidate="ValideEsto"
OnClientSideValidate=validarLongitud Display="Dynamic" ControlToValidate="tbNombreUsuario"
ErrorMessage="El nombre del usuario debe tener 8 o más caracteres."/>
EJERCICIOS
Generar dos cuadros de lista con elementos idénticos. Luego generar un control de validación que compare los
valores seleccionados y muestre un mensaje de error si no son iguales.
PREGUNTAS PARA ENTREGAR
• ¿Cuáles son los 5 controles de validación?
• Verdadero o falso: Los controles de validación validan en el cliente.
• ¿Cuáles son las propiedades que todo control de validación debería tener.
• ¿Qué hace el parámetro clienttarget=downlevel?
• ¿Qué propiedad del control CustomValidator necesita para establecer el controlador de evento?
• Si tuviera dos controles de servidor, tbNombre y tbEdad, ¿funcionaría el siguiente validador?
<asp:CompareValidator runat=server ControlToValidate=tbNombre ValueToCompare=tbEdad
ErrorMessage=¡Error!/>
TEMA 7: INTRODUCCIÓN A LAS BASES DE DATOS
COMO ACCEDER A DATOS CON ASP.NET
Cinco pasos:
• Configurar la conexión a la base de datos.
• Abrir la conexión.
• Llenar un conjunto de datos (DataSet) con los datos deseados.
• Establecer una vía de datos (DataView) para mostrar los datos.
• Establecer un control de servidor a una vista de datos mediante enlace de datos.
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
Hay que importar los espacios de nombres de datos
<script language="c#" runat="server">
public void Page_Load(Object obj, EventArgs e)
{
//Configurar conexión
OleDbConnection objConn= New OleDbConnection ("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\ASPNET\datos\bancario.mdb")
// Abrir conexión
100
OleDbDataAdapter objCmd = New OleDbDataAdapter("SELECT * FROM tblUsuarios;", objConn)
// Llenar conjunto de datos
DataSet ds = New DataSet()
objCmd.Fill(ds, "tblUsuarios")
//Seleccionar la vista de datos y vincularla con un control del servidor
Enlaza los datos a un control web DataList que despliega automáticamente los datos. Este control utiliza
plantillas para dar formato a los datos e itera automáticamente por los registros de la BBDD.
MiListaDeDatos.DataSource = ds.Tables("tblUsuarios").DefaultView
MiListaDeDatos.DataBind()
}
</script>
<html><body>
<ASP:DataList id="MiListaDeDatos" RepeatColumns="2" RepeatDirection="Vertical" runat="server">
<ItemTemplate>
<div style="padding:15,15,15,15;font−size:10pt; font−family:Verdana">
<div style="font:12pt verdana;color:darkred">
<i><b>
Las etiquetas <%# %> son expresiones de enlace de datos, que permite vincular explícitamente un origen de
datos a un control de servidor. Lo que ocurra en el origen de datos también ocurrirá en el control.
<%# DataBinder.Eval(Container.DataItem, "Nombre")%> 
<%# DataBinder.Eval(Container.DataItem, "Apellidos")%>
</i></b>
</div>
<br>
<b>Domicilio:</b>
<%#DataBinder.Eval(Container.DataItem, "Domicilio")%><br>
<b>Ciudad:</b>
101
<%#DataBinder.Eval(Container.DataItem,Ciudad")%><br>
<b>Estado: </b>
<%# DataBinder.Eval (Container.DataItem, "Estado") %><br>
<b>CodPostal: </b>
<%# DataBinder.Eval (Container.DataItem, "CodPostal") %><br>
<b>Telefono: </b>
<%# DataBinder.Eval (Container.DataItem, "Telefono") %><br>
</div>
</ItemTemplate>
</ASP:DataList>
</body></html>
TEMA 8: USO DE LAS BASES DE DATOS CON ASP.NET
EL OBJETO DATASET
Ado.Net gira entorno a este objeto. Reemplaza al RecordSet tradicional de ADO.
El DataSet es un sencillo almacén de datos residente en memoria qu ofrece un modelo de programación
consistente para acceder a datos, sin importar el tipo de éstos. El DataSet contiene conjuntos completos de
datos, como restricciones, relaciones e incluso varias tablas a la vez.
Imagina una caja con varios compartimentos. En cada uno puedes colocar el objeto que quieras siempre y
cuando quepa en la caja. Cuando estableces una conexión a la base de datos, le proporcionas a ésta una caja y
le indicas que la llene con algo.
Un objeto DataTable representa a una tabla de datos. El DataSet tiene una colección de estas tablas en el
objeto TablesCollection. El DataTable tiene otras dos colecciones Rows y Columns.
Imagina otra vez la caja. Cada compartimento es un DataTable.
COMO LLENAR UN DATASET
<%@ Page Language=c#%>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script runat="server">
public void Page_Load(Object obj, EventArgs e)
102
{
//Configurar conexión
OleDbConnection miConexion= New OleDbConnection ("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\\ASPNET\\datos\\bancario.mdb");
// Abrir conexión
OleDbDataAdapter miComando = New OleDbDataAdapter("SELECT * FROM tblUsuarios;", miConexion);
// Llenar conjunto de datos
DataSet ds = New DataSet();
miComando.Fill(ds, "tblUsuarios");
}
</script>
<html><body>
</body></html>
No es necesario crearse la tabla tblUsuarios. El DataSet lo hace por nosotros.
ENLACE DE DATOS
Se puede enlazar casi cualquier tipo de dato a cualquier control o a la propiedad de un control de una página.
Esto da un control total del modo en que los datos van del almacén de datos a la página y viceversa. Puedes
tan sólo mostrar datos al usuario, usarlos para establecer las propiedades de estilo de un control, o incluso
permitir que el usuario modifique los datos y que actualice en almacén de datos.
Dos formas de enlazar datos a una página asp.net: con la propiedad DataSource de un control o con una
expresión de enlace de datos. La primera es la más usada para controles más complejos de servidor. La
segunda se puede utilizar en cualquier parte. La sintaxis de una expresión de enlace de datos es la siguiente:
<%# propiedad o colección %>
Las expresiones para el enlace de datos sólo se evalúan con el método DataBind().
<script runat="server">
string strNombre=David;
string [] miMatriz={Hola, Mundo};
string micadena=David;
public void Page_Load(Object obj, EventArgs e)
103
{
Page.DataBind();
}
</script>
<html>
..
Mi nombre es <%# strNombre %>
<asp:ListBox DataSource='<%# miMatriz %>' runat=server/>
<asp:TextBox text='<%# miCadena %>' runat=server/>
..
</html>
Hay que tener cuidado de que las expresiones de datos devuelvan los tipos de datos que esperan los controles.
Por ejemplo, un cuadro de texto espera un valor de cadena. Si la expresión no devuelve una obtendremos un
error.
<asp:TextBox text='<%# miCadena.ToString() %>' runat=server/>
Si ejecutamos DataBind en la página evaluará toda expresión de enlace de datos en al página. Por lo general,
esto se hace en el Page_Load:
public void Page_Load(Object obj, EventArgs e)
{
DataBind();
}
USO DEL ENLACE DE DATOS
El verdadero potencial del enlace de datos proviene del uso de valores dinámicos en controles de servidor.
<script language="c#" runat="server">
public void Indice_Changed(Object obj, EventArgs e)
{
DataBind();
}
104
</script>
<html><body>
<form runat="server">
<asp:Listbox runat="server" id="lbColores"
width="150"
AutoPostBack=true
rows="1"
SelectionMode="Single"
OnSelectedIndexChanged="Indice_Changed" >
<asp:Listitem value="1">Rojo</asp:Listitem>
<asp:Listitem value=" 2">Azul</asp:Listitem>
<asp:Listitem value=" 3">Verde</asp:Listitem>
<asp:Listitem value=" 4">Amarillo</asp:Listitem>
</asp:Listbox><p>
Usamos una expresión para enlazar la propiedad SelectedItem del ListBox. Cuando cambia el índice
seleccionado ejecuta de nuevo DataBind para enlazar el nuevo valor al label.
<asp:Label id="lblMensaje" runat="server"
Text='<%# lbColores.SelectedItem.Text %>' />
</form>
</body></html>
Ver tema8/aa.aspx
Algunos controles de servidor también pueden enlazarse a clases de datos. Esto se hace con la propiedad
DataSource a la que sólo se accede en tiempo de diseño. Tan sólo hay que establecer esta propiedad a una
clase de datos (una matriz, por ejemplo) y ejecutar el DataBind.
<script language="vb" runat="server">
Sub Page_Load(obj as Object, e as EventArgs)
If Not Page.IsPostBack Then
' Genere una matriz de colores
105
dim arrColores() as string = _
{"rojo", "naranja", "amarillo", "verde", _
"azul", "añil", "violeta"}
lbColores.DataSource = arrColores
lbColores.SelectedIndex = 0
End If
DataBind()
End Sub
</script>
<html><body>
<form runat="server">
<asp:Listbox runat="server" id="lbColores"
width="150"
AutoPostBack="true"
SelectionMode="Single" >
</asp:Listbox><p>
<asp:Label id="lblMensaje" runat="server"
Text='<%# lbColores.selectedItem.Text %>' />
</form>
</body></html>
<script language="c#" runat="server">
public void Page_Load(Object obj, EventArgs e)
{
Al usar PostBack sólo generamos la matriz la primera vez que se vea la página.
if (!Page.IsPostBack)
{
106
//Genere una matriz de colores
string [] arrColores = {"rojo", "naranja", "amarillo", "verde","azul", "añil", "violeta"};
lbColores.DataSource = arrColores;
lbColores.SelectedIndex = 0;
}
DataBind();
}
</script>
<html><body>
<form runat="server">
<asp:Listbox runat="server" id="lbColores"
width="150"
AutoPostBack="true"
SelectionMode="Single" >
</asp:Listbox><p>
<asp:Label id="lblMensaje" runat="server"
Text='<%# lbColores.SelectedItem.Text %>' />
</form>
</body></html>
107
Ver tema8/9.7.aspx
Al usar PostBack sólo generamos la matriz la primera vez que se vea la página. Esta verificación también
tiene otro propósito, si la omitimos recibiremos un error de se encontró el valor null donde se requería una
instancia de un objeto de la etiqueta.
SIN POSTBACK CON POSTBACK
108
Evento Page−Load Evento Page−Load
Inicializar ListBox ¿Se envió el formulario?
(DataBind)
SI NO(Primera vista)
Controlar Cambio
(DataBind)
Controlar Cambio Inicializar ListBox
(DataBind) (DataBind)
Interpretar página Interpretar página
Interpretar página
CONTROLES ENLAZADOS A DATOS
Son los controles de lista: Repeater, DataList y DataGrid. Toman colecciones de datos e iteran por ellos
automáticamente. Similares a los demás controles, como DropDownList y ListBox, pero con funcionalidad
más compleja. Funcionan como contenedores de otros controles que realmente muestran los datos, como las
etiquetas.
EL CONTROL DE SERVIDOR REPEATER
Es contenedor que itera por los datos. No tiene un despliegue predeterminado. Hay que establecer su
disposición con controles de plantilla. Tiene una interfaz muy flexible. Si no se establece una disposición, el
control no será interpretado.
Las plantillas son controles que permiten usar etiquetas y texto HTML, así como otros controles para
controlasr el despliegue de datos en controles Web enriquecidos. El control Repeater permite los siguientes
tipos de plantillas:
ItemTemplate: Es necesaria para este control. Produce una fila de resultados para cada registro de datos. Usa
otros controles de servidor para mostrar los datos reales enlazándolos a los campos adecuados.
AlternatingItemTemplate: Igual que ItemTemplate, pero se interpreta para mostrar cada fila alternativa de
datos. Esto permite especificar diferentes configuraciones de estilo, como alternar colores de las filas.
HeaderTemplate y FooterTemplate: Generan directamente HTML antes y después de las filas de datos que
serán interpretadas. Un uso típico sería abrir y cerrar tablas con las etiquetas <table> y </table>.
SeparatorTemplate: Estas plantillas generan elementos entre cada fila de datos, como las etiquetas HTML
<br>,<p> o <HR>.
Estas plantillsa sólo se usan como contenedores para el despliegue de datos.
<%@ Page Language="VB" %>
109
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script runat="server">
Sub Page_Load(obj As Object, e As EventArgs)
' Establezca la conexión
Dim miConexion As New OleDbConnection _
("Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\ASPNET\datos\bancario.mdb")
' Abra la conexión
Dim miComando As New OleDbDataAdapter _
("SELECT * FROM tblUsuarios;", miConexion)
' Llene el conjunto de datos
Dim ds As DataSet = New DataSet()
miComando.Fill(ds, "tblUsuarios")
' Seleccione la vista de datos y vincúlela al control del servidor
Repeater1.DataSource = ds.Tables("tblUsuarios"). _
DefaultView
DataBind()
end sub
</script>
<html><body>
<ASP:Repeater id="Repeater1" runat="server" >
<HeaderTemplate>
<table>
<tr>
<td bgcolor="#cccc99" width=200><b>Nombre</b></td>
110
<td bgcolor="#cccc99" width=200><b>Teléfono</b></td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td> <%# Container.DataItem("Nombre") %> 
<%# Container.DataItem("Apellidos") %>
</td>
<td> <%# Container.DataItem("Telefono") %> </td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr>
<td bgcolor="#cccc99"">
<%# Container.DataItem("Nombre") %> 
<%# Container.DataItem("Apellidos") %>
</td>
<td bgcolor="#cccc99">
<%# Container.DataItem("Telefono") %>
</td>
</tr>
</AlternatingItemtemplate>
<SeparatorTemplate>
<tr>
<td colspan="2" align="center">
−−−
111
</td>
</tr>
</SeparatorTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</ASP:Repeater>
</body></html>
ver tema8/9.8VB
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="_9._8C.WebForm1" %>
<!DOCTYPE HTML PUBLIC "−//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<body>
Declaro el control Repeater
<asp:Repeater id="Repeater1" runat="server">
El encabezado sólo genera una tabla HTML y despliega los encabezados de las columnas nombre y teléfono
<HeaderTemplate>
<table>
<tr>
<td bgcolor="#cccc99" width=200><b>Nombre</b></td>
<td bgcolor="#cccc99" width=200><b>Teléfono</b></td>
</tr>
</HeaderTemplate>
Enlazamos tres controles de datos a la página en esta plantilla y el Repeater itera por por resultados.
<ItemTemplate>
<tr>
112
<td> <%# DataBinder.Eval(Container,"DataItem.Nombre") %> 
<%# DataBinder.Eval(Container,"DataItem.Apellidos") %>
</td>
<td> <%# DataBinder.Eval(Container,"DataItem.Telefono")%> </td>
</tr>
</ItemTemplate>
La plantilla alternativa muestra un color de fondo diferente para las distintas filas, por lo demás hace lo mismo
que el ItemTemplate.
<AlternatingItemTemplate>
<tr>
<td bgcolor="#cccc99"">
<%# DataBinder.Eval(Container,"DataItem.Nombre") %> 
<%# DataBinder.Eval(Container,"DataItem.Apellidos") %>
</td>
<td bgcolor="#cccc99">
<%# DataBinder.Eval(Container,"DataItem.Telefono") %>
</td>
</tr>
</AlternatingItemtemplate>
La plantilla separadora sólo añade un separador entre filas.
<SeparatorTemplate>
<tr>
<td colspan="2" align="center">
−−−
</td>
</tr>
</SeparatorTemplate>
113
La plantilla de pie cierra la tabla.
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</body>
</HTML>
ASPX.CS
private void Page_Load(object sender, System.EventArgs e)
{
OleDbConnection miConexion = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\\Documents and Settings\\mvaldericeda\\Escritorio\\asp.net\\Ejercicios\\bancario.mdb");
// Abre la conexión
OleDbDataAdapter miComando =new OleDbDataAdapter("SELECT * FROM tblUsuarios;", miConexion);
// Llena el conjunto de datos
DataSet ds = new DataSet();
miComando.Fill(ds, "tblUsuarios");
// Selecciona la vista de datos y la vinculas al control del servidor
Repeater1.DataSource = ds.Tables[0];
DataBind();
}
ver tema8/9.8C
El control Repeater tiene un evento:ItemCreated.
ItemCreated: Se desencadena siempre antes de que se genere un elemento o plantilla. Se puede usar para
establecer propiedades a través de código en tiempo de ejecución. Su sintaxis es:
Public void Nombre_ItemCreated (Object obj, RepeaterItemEventArgs e)
RepeaterItemEventArgs tiene la propiedad Item, que es el elemento que ha generado.
114
public void Repeater1_ItemCreated (object obj, RepeaterItemEventArgs e)
{
string tipo="";
switch (e.Item.ItemType)
{
case ListItemType.Item:
tipo="Item";
break;
case ListItemType.AlternatingItem:
tipo="AlternatingItem";
break;
case ListItemType.Header:
tipo="Header";
break;
case ListItemType.Footer:
tipo="Footer";
break;
case ListItemType.Separator:
tipo="Separator";
break;
}
Label1.Text=Label1.Text + "Se ha generado un " + tipo + " del repetidor <br>";
}
ver tema8/Rep1
El control Repeater sólo presenta datos, no permite que los usuarios modifiquen el origen de datos. Si quieres
permitirlo tendrás que usar los controles DataList o DataGrid.
EL CONTROL DE SERVIDOR DATALIST
115
Similar al Repeater, excepto que permite la comunicación con el usuario y la modificación de los datos. Este
control se puede usar con plantillas para listar elementos como lo haría el Repeater. Pero el DataList sólo
admite dos tipos de plantillas adicionales:
SelectedItemTemplate: Contiene elementos adicionales que serán interpretados sólo cuando el usuario elija
un elemento en el control DataList. Usos típicos:modificar las propiedades de estilo para reflejar la selección
de una fila, o expandir el elemento como en un listado jerárquico (principal y secundario).
EditItemTemplate: Especifica la disposición de un elemento cuando se encuetre en modo edición.
Trabajar con DataList
El control DataList muestra los elementos de datos en una lista de repeticiones y admite opcionalmente la
selección y edición de elementos. El contenido y diseño de los elementos de la lista de DataList se define
utilizando plantillas. Como mínimo, todos los controles DataList deben definir un ItemTemplate; sin
embargo, algunas plantillas opcionales se pueden utilizar para personalizar el aspecto de la lista. La siguiente
tabla enumera las plantillas.
Nombre de la plantilla
ItemTemplate
AlternatingItemTemplate
Plantilla del separador
SelectedItemTemplate
EditItemTemplate
Plantilla de encabezado
Plantilla de pie de página
Descripción
Define el contenido y diseño de los elementos de la lista.
Requerido.
Si se define, determina el contenido y diseño de elementos
alternos. Si no se define, se utiliza ItemTemplate.
Si se define, se procesa entre elementos (y elementos alternos).
Si no se define, no se procesa el separador.
Si se define, determina el contenido y diseño del elemento
seleccionado. Si no se define, se utiliza ItemTemplate
(AlternatingItemTemplate).
Si se define, determina el contenido y diseño del elemento que
se edita. Si no se define, se utiliza ItemTemplate
(AlternatingItemTemplate, SelectedItemTemplate).
Si se define, determina el contenido y diseño del encabezado de
la lista. Si no se define, no se procesa el encabezado.
Si se define, determina el contenido y diseño del pie de página
de la lista. Si no se define, no se procesa el pie de página.
Las plantillas definen los elementos y controles HTML que se deben mostrar para un elemento, así como el
diseño de estos elementos. El formato de estilo: fuente, color y atributos de bordes, se establece a través de los
estilos. Cada plantilla tiene su propiedad de estilo. Por ejemplo, los estilos de EditItemTemplate se
establecen mediante la propiedad EditItemStyle.
Un tercer conjunto de propiedades afectan al procesamiento general de DataList. De forma predeterminada,
los elementos de DataList se procesan en una tabla como una columna individual vertical. Al establecer la
propiedad RepeatLayout en Flow se quita la estructura de tabla HTML del procesamiento de la lista.
DataList admite procesamiento direccional mediante la propiedad RepeatDirection, es decir, que puede
procesar los elementos horizontal o verticalmente. Dado que el ancho de página es la dimensión que el
desarrollador debe controlar en la interfaz de usuario Web, el control DataList permite que el desarrollador
controle el número de columnas que se procesan (RepeatColumns), independientemente de si se procesan
horizontal o verticalmente los elementos.
116
Si RepeatDirection es igual a Horizontal y RepeatColumns es cinco, los elementos se procesan en filas que
contienen cinco columnas.
1
6
11
2
7
12
3
8
13
4
9
5
10
Si RepeatDirection es igual a Vertical y RepeatColumns está establecido en cinco, los elementos se
procesan en cinco columnas, cada una igual en longitud al número total de elementos dividido por cinco.
1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ Page Language="VB" Debug="true"%>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script runat="server">
Sub Page_Load(obj As Object, e As EventArgs)
' Establezca la conexión
Dim miConexion As New OleDbConnection _
("Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Inetpub\wwwroot\bancario.mdb")
' Abra la conexión
Dim miComando As New OleDbDataAdapter _
("SELECT * FROM tblUsuarios;", miConexion)
' Llene el conjunto de datos
Dim ds As DataSet = New DataSet()
miComando.Fill(ds, "tblUsuarios")
' Seleccione la vista de datos y vincúlela al control del servidor
DataList1.DataSource = ds.Tables("tblUsuarios"). _
DefaultView
DataBind()
117
end sub
sub DataList1_ItemCommand(obj As object, e As _
DataListCommandEventArgs)
DataList1.SelectedIndex = e.Item.ItemIndex
DataList1.DataBind()
end sub
</script>
<html><body><Form runat="server">
<asp:DataList id="DataList1" runat="server"
SelectedItemStyle−BackColor="#cccc99"
repeatlayout="table"
repeatdirection="horizontal"
DataKeyField="IDUsuario"
OnItemCommand="DataList1_ItemCommand">
<ItemTemplate>
<asp:LinkButton id="button1" runat="server"
Text='<%# Container.DataItem("Nombre") & " " & _
Container.DataItem("Apellidos") %>'
CommandName="Select" />
<p>
</ItemTemplate>
<SelectedItemTemplate>
<%# Container.DataItem("Nombre") & " " & _
Container.DataItem("Apellidos") %><br>
Teléfono:
<%# Container.DataItem("Telefono") %>
118
<br>
Domicilio:
<%# Container.DataItem("Domicilio") %>
<br>
<%# Container.DataItem("Ciudad") %>,
<%# Container.DataItem("Estado") %>
 <%# Container.DataItem("codpostal") %>
<br>
</SelectedItemTemplate>
</asp:DataList>
</form>
</body></html>
Ver tema8/dataListVB.aspx
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="DataList1.WebForm1" %>
<!DOCTYPE HTML PUBLIC "−//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
Declaro un control DataList
119
SelectedItemStyle−BackColor define el color de fondo de SelectedItemTemplate cuando está visible.
DataKeyField es el nombre del campo que se usará como clave principal de los datos.
<asp:DataList id="DataList1" runat="server"
SelectedItemStyle−BackColor="#cccc99"
repeatlayout="table"
repeatdirection="horizontal"
DataKeyField="IDUsuario"
OnItemCommand="DataList1_ItemCommand">
<ItemTemplate>
Genero un control LinkButton que está enlazado a las columnas Nombre y Apellidos. Cuando se haga
clic en el vínculo, generará y pasará el comando Select al DataList.
<asp:LinkButton id="button1" runat="server" CommandName="Select" >
<%# DataBinder.Eval(Container,"DataItem.Nombre")%>
<%#DataBinder.Eval(Container,"DataItem.Apellidos") %>
</asp:LinkButton>
<p>
</ItemTemplate>
Esta plantilla muestra información enlazada a los datos.
<SelectedItemTemplate>
<%# DataBinder.Eval(Container,"DataItem.Nombre")%>
<%# DataBinder.Eval(Container,"DataItem.Apellidos")%><br>
Teléfono:
<%# DataBinder.Eval(Container,"DataItem.Telefono") %>
<br>
Domicilio:
<%# DataBinder.Eval(Container,"DataItem.Domicilio") %>
<br>
120
<%# DataBinder.Eval(Container,"DataItem.Ciudad") %>,
<%# DataBinder.Eval(Container,"DataItem.Provincia") %>
 <%# DataBinder.Eval(Container,"DataItem.codpostal") %>
<br>
</SelectedItemTemplate>
</asp:DataList>
</form>
</body>
</HTML>
.ASPX.CS
private void Page_Load(object sender, System.EventArgs e)
{
OleDbConnection miConexion = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\\Inetpub\\wwwroot\\bancario.mdb");
// Abre la conexión
OleDbDataAdapter miComando =new OleDbDataAdapter("SELECT * FROM tblUsuarios;", miConexion);
// Llena el conjunto de datos
DataSet ds = new DataSet();
miComando.Fill(ds, "tblUsuarios");
// Selecciona la vista de datos y vincúlela al control del servidor
DataList1.DataSource = ds.Tables[0];
DataBind();
}
public void DataList1_ItemCommand(object obj,DataListCommandEventArgs e)
{
DataList1.SelectedIndex = e.Item.ItemIndex;
DataList1.DataBind();
121
}
Ver tema8/DataList1
Ejercicio:
Tenemos un DataList, tres DropDown y un CheckBox. El DataList debe cambiar el aspecto según
seleccionemos. Dirección: Horizontal o Vertical. Layout: Tabla o Flor. Columnas de 1 a 5.
122
123
124
Solución tema8/ejercicio1
MODIFICACIÓN DE ELEMENTOS
El control DataList admite la edición directa de los datos de un elemento mediante la propiedad
EditItemTemplate . EditItemTemplate define el contenido y el aspecto del elemento cuando se está editando.
Por ejemplo, la siguiente plantilla incluye un cuadro de texto, un botón "Actualizar" y un botón "Cancelar".
<EditItemTemplate>
Item:
<asp:TextBox id="Text1" runat="server"
Text='<%# ((DataRowView)Container.DataItem)["Item"] %>' />
<br>
<asp:LinkButton id="button1" runat="server" Text="Update" CommandName="update" />
<asp:LinkButton id="button2" runat="server"Text="Cancel"
125
CommandName="cancel"/>
</EditItemTemplate>
EditItemTemplate interactúa con otra propiedad: EditItemIndex. De forma predeterminada, el valor de
EditItemIndex es igual a −1, es decir, no se está editando ninguno de los elementos de la lista. Cuando
EditItemIndex se establece en un elemento determinado, ese elemento se muestra utilizando
EditItemTemplate.
DataList también proporciona tres eventos que se pueden utilizar por compatibilidad con la edición. Se inicia
EditCommand cuando se hace clic en el control del botón de comando "Editar" en ItemTemplatede la lista.
El control de este evento en el código depende del usuario. La lógica típica establece EditItemIndex en el
elemento seleccionado y, a continuación, vuelve a enlazar los datos de DataList como se muestra en el
siguiente ejemplo:
protected void DataList_EditCommand(object Source,DataListCommandEventArgs e)
{
DataList1.EditItemIndex = (int)e.Item.ItemIndex;
BindList();
}
EditItemTemplate contiene normalmente botones de comando "Actualizar" y "Cancelar". Estos botones
provocan que se inicien los eventos UpdateCommand y CancelCommand, respectivamente. Controlar estos
eventos en el código depende del usuario. La lógica típica de "Cancelar" establece EditItemIndex en −1 y, a
continuación, vuelve a enlazar los datos de DataList como muestra el siguiente ejemplo:
protected void DataList_CancelCommand(object Source, DataListCommandEventArgs e)
{
DataList1.EditItemIndex = −1;
BindList();
}
Protected Sub DataList_CancelCommand(Source As Object, e As DataListCommandEventArgs)
DataList1.EditItemIndex = −1
BindList()
End Sub
protected function DataList_CancelCommand(Source:Object, e:DataListCommandEventArgs) : void {
DataList1.EditItemIndex = −1;
BindList();
126
}
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script runat="server">
Sub Page_Load(obj As Object, e As EventArgs)
' Establezca la conexión
Dim miConexion As New OleDbConnection _
("Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\ASPNET\datos\bancario.mdb")
' Abra la conexión
Dim miComando As New OleDbDataAdapter _
("SELECT * FROM tblUsuarios;", miConexion)
' Llene el conjunto de datos
Dim ds As DataSet = New DataSet()
miComando.Fill(ds, "tblUsuarios")
' Seleccione la vista de datos y vincúlela al control del servidor
DataList1.DataSource = ds.Tables("tblUsuarios"). _
DefaultView
DataBind()
end sub
Sub DataList1_ItemCommand(obj As object, e As _
DataListCommandEventArgs)
DataList1.SelectedIndex = e.Item.ItemIndex
DataList1.DataBind()
End Sub
127
sub DataList1_EditCommand(obj As object, e As _
DataListCommandEventArgs)
DataList1.EditItemIndex = e.Item.ItemIndex
DataList1.DataBind()
end sub
Sub DataList1_CancelCommand(obj As object, e As _
DataListCommandEventArgs)
DataList1.EditItemIndex = −1
DataList1.DataBind()
End Sub
Sub DataList1_UpdateCommand(obj As object, e As _
DataListCommandEventArgs)
' Actualizar el almacén de datos
DataList1.DataBind()
End Sub
Sub DataList1_DeleteCommand(obj As object, e As _
DataListCommandEventArgs)
' Suprimir del almacén de datos
DataList1.DataBind()
End Sub
</script>
<html><body><Form runat="server">
<asp:DataList id="DataList1" runat="server"
SelectedItemStyle−BackColor="#cccc99"
repeatlayout="table"
repeatdirection="horizontal"
128
OnItemCommand="DataList1_ItemCommand"
OnEditCommand="DataList1_EditCommand"
OnCancelCommand="DataList1_CancelCommand"
OnUpdateCommand="DataList1_UpdateCommand"
OnDeleteCommand="DataList1_DeleteCommand"
DataKeyField="IDUsuario">
<ItemTemplate>
<asp:LinkButton id="button1" runat="server"
Text='<%# Container.DataItem("Nombre") & _
" " & Container.DataItem("Apellidos") %>'
CommandName="Edit" />
<p>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton id="lbtCancel" runat="server"
CommandName="Cancel"
Text="Cancelar" />
<asp:LinkButton id="lbtUpdate" runat="server"
CommandName="Update"
Text="Actualizar" />
<asp:LinkButton id="lbtDelete" runat="server"
CommandName="Delete"
Text="Suprimir" />
</EditItemTemplate>
</asp:DataList>
</form>
129
</body></html>
Ver tema8/DataListVB2
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="DataList1.WebForm1" %>
<!DOCTYPE HTML PUBLIC "−//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:DataList id="DataList1" runat="server"
SelectedItemStyle−BackColor="#cccc99"
repeatlayout="table"
repeatdirection="horizontal"
DataKeyField="IDUsuario"
OnItemCommand="DataList1_ItemCommand">
<ItemTemplate>
<asp:LinkButton id="button1" runat="server" CommandName="Edit" >
<%# DataBinder.Eval(Container,"DataItem.Nombre")%>
<%#DataBinder.Eval(Container,"DataItem.Apellidos") %>
</asp:LinkButton>
<p>
130
</ItemTemplate>
<SelectedItemTemplate>
<%# DataBinder.Eval(Container,"DataItem.Nombre")%>
<%# DataBinder.Eval(Container,"DataItem.Apellidos")%><br>
Teléfono:
<%# DataBinder.Eval(Container,"DataItem.Telefono") %>
<br>
Domicilio:
<%# DataBinder.Eval(Container,"DataItem.Domicilio") %>
<br>
<%# DataBinder.Eval(Container,"DataItem.Ciudad") %>,
<%# DataBinder.Eval(Container,"DataItem.Provincia") %> 
<%# DataBinder.Eval(Container,"DataItem.codpostal") %>
<br>
</SelectedItemTemplate>
<EditItemTemplate>
<asp:LinkButton id="lbtCancel" runat="server"
CommandName="Cancel"
Text="Cancelar" />
<asp:LinkButton id="lbtUpdate" runat="server"
CommandName="Update"
Text="Actualizar" />
<asp:LinkButton id="lbtDelete" runat="server"
CommandName="Delete"
Text="Suprimir" />
</EditItemTemplate>
131
</asp:DataList>
</form>
</body>
</HTML>
Este listado aún no funcionará. Primero hay que definir los métodos para controlar sus eventos. Cuando los
usuarios hagan clic en cada elemento, parecerá un menú de opciones, gracias al EditItemTemplate.
También se ha modificado el comando Select del LinkButton a Edit. Este es un comando que desencadena
automáticamente el evento EditCommand del DataList. Tendremos que declarar un controlador de evento.
public void DataList1_EditCommand(object obj,DataListCommandEventArgs e)
{
DataList1.EditItemIndex=e.Item.ItemIndex;
DataList1.DataBind();
}
Establecemos la propiedad EditItemIndex al elemento seleccionado, y cambia a modo de edición para ese
elemento para que el usuario modifique los campos, lo que a la vez acrualizará el almacén de datos.
public void DataList1_CancelCommand(object obj,DataListCommandEventArgs e)
{
DataList1.EditItemIndex=−1;
DataList1.DataBind();
}
public void DataList1_UpdateCommand(object obj,DataListCommandEventArgs e)
{
DataList1.DataBind();
}
public void DataList1_DeleteCommand(object obj,DataListCommandEventArgs e)
{
DataList1.DataBind();
}
132
Ver tema8/DataList2
EL CONTROL DE SERVIDOR DATAGRID
Similar a los controles DataList y Repeater, excepto porque ofrece más funcionalidad. Utiliza columnas para
mostrar los datos en un diseño de cuadrícula. De forma predeterminada genera una columna para cada campo
del almacén de datos. Se puede especificar manualmente qué campos desplegar y cómo desplegarlos. Tipos de
columnas:
Columnas Enlazadas: Permiten especificar cuáles columnas mostrar y en qué orden, y dar formato a los
atributos de estilo. Son las que usa de forma predeterminada.
Columnas de Botón: Muestran botones para todos los elementos de la cuadrícula, par los cuales definirá una
funcionalidad propia.
Columnas del comando Edit: Permite modificar elementos.
Columnas de hipervínculo: Muestra los datos como hipervínculos.
Columnas por plantillas: Se pueden usar plantillas, como con los controles Repeater y DataList, para definir
formatos propios para las columnas.
El control DataGrid elige automáticamente un tipo de columna de acuerdo con los datos que se mostrarán.
Ejemplo de DataGrid
<%@ Page Language="VB" Debug="true"%>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script runat="server">
Sub Page_Load(obj As Object, e As EventArgs)
try
' Establezca la conexión
Dim miConexion As New OleDbConnection _
("Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Inetpub\wwwroot\bancario.mdb")
' Abra la conexión
Dim miComando As New OleDbDataAdapter _
("SELECT * FROM tblUsuarios;", miConexion)
133
' Llene el conjunto de datos
Dim ds As DataSet = New DataSet()
miComando.Fill(ds, "tblUsuarios")
' Seleccione la vista de datos y vincúlela al control del servidor
DataGrid1.DataSource = ds.Tables("tblUsuarios").DefaultView
DataBind()
catch ex as Exception
Response.Write (ex.Message)
end try
end sub
</script>
<html><body><Form runat="server">
<asp:DataGrid id="DataGrid1" runat="server"
BorderColor="black"
GridLines="Vertical"
cellpadding="4"
cellspacing="0"
width="450"
Font−Names="Arial"
Font−Size="8pt"
ShowFooter="True"
HeaderStyle−BackColor="#cccc99"
FooterStyle−BackColor="#cccc99"
ItemStyle−BackColor="#ffffff"
AlternatingItemStyle−Backcolor="#cccccc"
AutoGenerateColumns="True">
134
<Columns>
<asp:TemplateColumn HeaderText="Nombre">
<ItemTemplate>
<asp:Label id="Nombre" runat="server"
Text='<%# Container.DataItem("Nombre")& _
" " & Container.DataItem("Apellidos") %>'/>
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn HeaderText="Domicilio"
DataField="Domicilio"/>
<asp:BoundColumn HeaderText="Ciudad" DataField="Ciudad"/>
<asp:BoundColumn HeaderText="Provincia"
DataField="Provincia" />
<asp:BoundColumn HeaderText="Código postal" DataField="codPostal" />
<asp:HyperlinkColumn HeaderText="Modificar" text="Modificar"
NavigateURL="edit.aspx"/>
<asp:ButtonColumn HeaderText="¿Suprimir?" text="X"
CommandName="delete"
ButtonType="PushButton"/>
</Columns>
</asp:DataGrid>
</form>
</body></html>
Ver tema8/dg1VB.aspx
<%@ Page Language="C#" Debug="true"%>
<%@ Import Namespace="System.Data" %>
135
<%@ Import Namespace="System.Data.OleDb" %>
<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
try
{
// Establezco la conexión
OleDbConnection miConexion= new OleDbConnection ("Provider= Microsoft.Jet.OLEDB.4.0;" + "Data
Source=C:\\Inetpub\\wwwroot\\bancario.mdb");
// Abro la conexión
OleDbDataAdapter miComando = new OleDbDataAdapter("SELECT * FROM tblUsuarios;",
miConexion);
// Lleno el conjunto de datos
DataSet ds= new DataSet();
miComando.Fill(ds, "tblUsuarios");
// Selecciono la vista de datos y la vinculo al control del servidor
DataGrid1.DataSource = ds.Tables["tblUsuarios"].DefaultView;
DataGrid1.DataBind();
}
catch (Exception ex)
{
Response.Write (ex.Message);
}
}
</script>
<html>
<body>
136
<Form runat="server">
Establezco las propiedades del DataGrid
<asp:DataGrid id="DataGrid1" runat="server"
BorderColor="black"
GridLines="Vertical"
cellpadding="4"
cellspacing="0"
width="450"
Font−Names="Arial"
Font−Size="8pt"
ShowFooter="True"
HeaderStyle−BackColor="#cccc99"
FooterStyle−BackColor="#cccc99"
ItemStyle−BackColor="#ffffff"
AlternatingItemStyle−Backcolor="#cccccc"
En esta línea le indico al DataGrid que quiero configurar mis propias columnas
AutoGenerateColumns="True">
Para definir las columnas personalizadas tendré que agregarlas a la colección Columns del DataGrid.
TemplateColumn, HyperlinkColumn, BoundColumn y ButtonColumn son controles utilizados
específicamente para el control DataGrid.
<Columns>
<asp:TemplateColumn HeaderText="Nombre">
<ItemTemplate>
<asp:Label id="Nombre" runat="server"
Text='<%# DataBinder.Eval(Container.DataItem,"Nombre") + " " +
DataBinder.Eval(Container.DataItem,"Apellidos") %>'/>
</ItemTemplate>
137
</asp:TemplateColumn>
BoundColumn utiliza la propiedad DataField para para enlazarse al almacén de datos.
<asp:BoundColumn HeaderText="Domicilio"
DataField="Domicilio"/>
<asp:BoundColumn HeaderText="Ciudad" DataField="Ciudad"/>
<asp:BoundColumn HeaderText="Provincia"
DataField="Provincia" />
<asp:BoundColumn HeaderText="Código postal" DataField="codPostal" />
<asp:HyperlinkColumn HeaderText="Modificar" text="Modificar"
NavigateURL="edit.aspx"/>
ButtonColumn muestra de forma predeterminada un control LinkButton, pero puede usar la
propiedad ButtonType para establecer un tipo distinto.
<asp:ButtonColumn HeaderText="¿Suprimir?" text="X"
CommandName="delete"
ButtonType="PushButton"/>
</Columns>
</asp:DataGrid>
</form>
</body></html>
Ver tema8/dg1C.aspx
DataBinder.Eval
El marco de trabajo ASP.NET proporciona un método estático que evalúa expresiones de enlace de datos
enlazadas en tiempo de ejecución y, de forma opcional, aplica un formato de cadena al resultado.
DataBinder.Eval resulta práctico en cuanto a que elimina gran parte de la conversión de tipos explícita que
debe realizar el programador para convertir valores en el tipo de datos deseado. Resulta especialmente útil al
enlazar datos con controles en una lista con plantillas, ya que con frecuencia la fila de datos y el campo de
datos deben estar convertidos.
Considérese el siguiente ejemplo, en el que un entero se visualiza como una cadena de moneda. Con la
sintaxis de enlace de datos estándar de ASP.NET, se debe realizar primero la conversión del tipo de la fila de
datos para recuperar el campo de datos, IntegerValue. A continuación, se pasa como argumento al método
String.Format.
138
<%# String.Format("{0:c}", ((DataRowView)Container.DataItem)["IntegerValue"]) %>
Esta sintaxis puede resultar compleja y difícil de recordar. En contraste, DataBinder.Eval es simplemente un
método con tres argumentos: el contenedor que da nombre al elemento de datos, el nombre del campo de
datos y una cadena de formato. En una lista con plantillas, como DataList, DataGrid o Repeater, el contenedor
que da nombre es siempre Container.DataItem. Page es otro contenedor de nombres que se puede utilizar con
DataBinder.Eval.
<%# DataBinder.Eval(Container.DataItem, "IntegerValue", "{0:c}") %>
MODIFICACIÓN DE ELEMENTOS
Simplemente hay que generar un EditCommandColumn.
<asp:DataGrid id="DataGrid1" runat="server"
BorderColor="black"
GridLines="Vertical"
cellpadding="4"
cellspacing="0"
width="450"
Font−Names="Arial"
Font−Size="8pt"
ShowFooter="True"
HeaderStyle−BackColor="#cccc99"
FooterStyle−BackColor="#cccc99"
ItemStyle−BackColor="#ffffff"
AlternatingItemStyle−Backcolor="#cccccc"
AllowSorting="False"
AutoGenerateColumns="False"
AllowPaging="True"
PageSize=2
PagerStyle−Mode=NumericPages
PagerStyle−PageButtonCount=2
139
OnPageIndexChanged="DataGrid1_PageIndexChanged"
OnEditCommand="DataGrid1_Edit"
OnCancelCommand="DataGrid1_Cancel"
OnUpdateCommand="DataGrid1_Update">
<Columns>
<asp:TemplateColumn HeaderText="Nombre">
<ItemTemplate>
<asp:Label id="Nombre" runat="server"
Text='<%# Container.DataItem("Nombre")& _
" " & Container.DataItem("Apellidos") %>'/>
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn HeaderText="Domicilio"
DataField="Domicilio"/>
<asp:BoundColumn HeaderText="Ciudad" DataField="Ciudad"/>
<asp:BoundColumn HeaderText="Estado"
DataField="Estado" />
<asp:BoundColumn HeaderText="Código postal" DataField="codPostal" />
<asp:EditCommandColumn
EditText="Modificar"
CancelText="Cancelar"
UpdateText="Actualizar"
ItemStyle−Wrap="false"
Muestra un LinkButton con el texto Modificar. Cuando el usuario haga clic, el elemento seleccionado
entrará a modo edición y cada columna cambiará a cuadro de texto. También muestra los vínculos
Actualizar y Cancelar. Hay que definir métodos para controlar estos eventos.
HeaderText="Modificar" />
140
</Columns>
</asp:DataGrid>
Puesto que se ha generado un EditCommandColumn se puede suprimir el HyperLinkColumn:
<asp:HyperlinkColumn HeaderText="Modificar" text="Modificar"
NavigateURL="edit.aspx"/>
Y también el ButtonColumn:
<asp:ButtonColumn HeaderText="¿Suprimir?" text="X"
CommandName="delete"
ButtonType="PushButton"/>
Porque EditCommandColumn agregará uno automáticamente.
Sólo BoundColumns cambiará a campos modificables. El resto, como TemplateColumns, mantendrá su
interfaz original. Hay que asegurarse de que las columnas que va a modificar el usuario sean BoundColumns.
Métodos para controlar Actualizar y Cancelar:
public void DataGrid1_Editar(object obj, DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = (int)e.Item.ItemIndex;
DataGrid1.DataBind();
}
public void DataGrid1_Update(object obj, DataGridCommandEventArgs e)
{
//Realizar actualizaciones
DataGrid1.DataBind();
}
public void DataGrid1_Cancel(object obj, DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = −1;
DataGrid1.DataBind();
141
}
Ver tema8/dataG.aspx
ORDENAMIENTO
Cuando activas el ordenamiento, de forma predeterminada el DataGrid convierte todos los encabezados en un
LinkButton en el que los usuarios pueden hacer clic para ordenar en base a esa columna. Hay que generar un
mecanismo de ordenamiento, pero asp.net da los fundamentos. También se puede especificar un ordenamiento
personalizado, en el que se defina las columnas por las que el usuario puede ordenar.
Cuando la propiedad AllowSorting de DataGrid se establece en true, procesa hipervínculos para los
encabezados de columna que desencadenan un comando Sort de nuevo en la cuadrícula. La propiedad
OnSortCommand de DataGrid se establece en el controlador al que se desea llamar cuando el usuario hace
clic en un vínculo de columna. El nombre de la columna se pasa como una propiedad SortExpression en el
argumento DataGridSortCommandEventArgs, que se puede utilizar para establecer la propiedad Sort del
enlace DataView en la cuadrícula.
Ejemplo:
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<%@ Page Language="C#" Debug="true" %>
<html>
<script runat="server">
OleDbConnection myConnection;
protected void Page_Load(Object sender, EventArgs e)
{
myConnection = new OleDbConnection("Provider= Microsoft.Jet.OLEDB.4.0;" + "Data
Source=C:\\Inetpub\\wwwroot\\bancario.mdb");
if (!IsPostBack)
BindGrid("IDUsuario"); // La primera vez aparece ordenado por IDUsuario
}
protected void MyDataGrid_Sort(Object sender, DataGridSortCommandEventArgs e)
{
BindGrid(e.SortExpression);
142
//Llama al método BindGrid y le dice por que columna ordenamos
}
public void BindGrid(String sortfield) //recibe la columna por la que ordenar
{
OleDbDataAdapter myCommand = new OleDbDataAdapter("SELECT * FROM tblUsuarios;",
myConnection);
DataSet ds = new DataSet();
myCommand.Fill(ds, "tblUsuarios");
DataView Source = ds.Tables["tblUsuarios"].DefaultView;
//genera una vista de datos
Source.Sort = sortfield;
//establece la propiedad Sort a sortfield (ordena por campo)
MyDataGrid.DataSource=Source;
MyDataGrid.DataBind();
}
</script>
<body>
<h3><font face="Verdana">Ordenar datos en un control DataGrid</font></h3>
<form runat="server">
<ASP:DataGrid id="MyDataGrid" runat="server" OnSortCommand="MyDataGrid_Sort"
Width="700"
BackColor="#ccccff"
BorderColor="black"
ShowFooter="false"
CellPadding=3
CellSpacing="0"
Font−Name="Verdana"
143
Font−Size="8pt"
HeaderStyle−BackColor="#aaaadd"
AllowSorting="true"
/>
</form>
</body>
</html>
Ver tema8/OrdenDataGrid.aspx
PAGINACIÓN
El DataGrid puede dividir los datos en varias páginas si hay demasiados registros para mostrarlos en una sola.
Asp.net dividirá los datos en las páginas que le indiquemos y creará botones para pasar de una a otra.
Usaremos la propiedad CurrentPageIndex del DataGrid para determinar cuál página deberá mostrarse. Cuando
el usuario haga clic en un botón para ir a la siguiente página, todos los datos serán generados y el proceso se
repetirá.
Para activar la paginación hay que establecer AllowPaging=True (esto es verdadero de forma
predeterminada), y la propiedad PageSize en la cantidad de registros que queremos mostrar a la vez. El estilo
de los botones de paginación se obtiene mediante la propiedad PagerStyle. Los dos estilos integrados son los
botones Siguiente y Anterior, y los números de página.
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<%@ Page Language="C#" Debug="true" %>
<html>
<script runat="server">
OleDbConnection myConnection;
protected void Page_Load(Object sender, EventArgs e)
{
myConnection = new OleDbConnection("Provider= Microsoft.Jet.OLEDB.4.0;" + "Data
Source=C:\\Inetpub\\wwwroot\\bancario.mdb");
if (!IsPostBack)
BindGrid("IDUsuario");
144
}
protected void MyDataGrid_Sort(Object sender, DataGridSortCommandEventArgs e)
{
BindGrid(e.SortExpression);
}
public void BindGrid(String sortfield)
{
OleDbDataAdapter myCommand = new OleDbDataAdapter("SELECT * FROM tblUsuarios;",
myConnection);
DataSet ds = new DataSet();
myCommand.Fill(ds, "tblUsuarios");
DataView Source = ds.Tables["tblUsuarios"].DefaultView;
Source.Sort = sortfield;
MyDataGrid.DataSource=Source;
MyDataGrid.DataBind();
}
public void MyDataGrid_PageIndexChanged(Object obj,DataGridPageChangedEventArgs e)
{
MyDataGrid.CurrentPageIndex = e.NewPageIndex;
//MyDataGrid.DataBind();
BindGrid("IDUsuario");
}
</script>
<body>
<h3><font face="Verdana">Ordenar datos en un control DataGrid</font></h3>
<form runat="server">
<ASP:DataGrid id="MyDataGrid" runat="server" OnSortCommand="MyDataGrid_Sort"
145
Width="700"
BackColor="#ccccff"
BorderColor="black"
ShowFooter="false"
CellPadding=3
CellSpacing="0"
Font−Name="Verdana"
Font−Size="8pt"
HeaderStyle−BackColor="#aaaadd"
AllowSorting="true"
AllowPaging="true"
PageSize=3
PagerStyle−Mode=NumericPages //NextPrev
PagerStyle−PageButtonCount = 2
OnPageIndexChanged="MyDataGrid_PageIndexChanged"/>
</form>
</body>
</html>
Ver tema8/OrdenDataGrid1.aspx
PREGUNTAS PARA ENTREGAR EN PAPEL
• ¿Qué espacios de nombres deberás importar para usar los mecanismos de datos en las páginas asp.net?
• Verdadero o falso: El DataSet puede contener varias tablass.
• ¿Cuáles son las tres colecciones del DataSet y qué hacen?
• ¿Cuál es la sintaxis para expresiones enlazadas a datos?
• ¿El control DataList admite paginación?
• ¿Cuáles son las dos propiedades de un DataGrid que debes especificar para activar la ordenación y la
paginación, respectivamente?
TEMA 9: COMUNICACIÓN CON ADO.NET
ADO.NET Y XML
146
XML es una herramienta muy útil para la distribución de datos. Está totalmente basado en texto, lo que
significa que las personas lo pueden escribir y leer fácilmente y puede transportarse según las medidas de
seguridad establecidas en internet.
XML almacena los datos proporcionando una representación jerárquica de campos y sus datos.
ADO.Net utliza XML en todos los intercambios de datos y para la representación interna de los datos. Tan
pronto como salen los datos de una base de datos, se representan en XML y se envían a donde los necesite.
EL MODELO DE OBJETOS ADO.NET
ADO.Net consta de dos partes clave: el DataSet y los proveedores administrados.
Los proveedores administrados fungen como una capa de comunicación entre un DataSet y un almacén de
datos. Proporcionan los mecanismos de conexión, acceso, manejo y recuperación de información de cualquier
almacén de datos compatible con OLEDB.
OLE DB y SQL.
UNA REVISIÓN DEL DATASET
El DataSet está desconectado. Cada usuario recibe su propia copia de los datos para hacer con ellos lo que
quiera. Las modificaciones hechas al DataSet NO se reflejan en el origen de datos. Cualquier modificación
deberá ser enviada explícitamente al origen de datos.
MODIFICACIÓN DE DATOS EN UN DATAROW
El DataSet almacena los datos de forma similar a una base de datos, contiene tablass, columnas y filas. Se
manipularán los datos con instrucciones sql que modifican más de un registro a la vez, pero habrá ocasiones
en que tendremos que tener un control más directo de cada fila. El objeto DataRow representa una fila de
datos del DataTable. Se puede modificar directamente el contenido de cada DataRow.
La propiedad RowState indica la condición de la fila: Detached, Unchanged, New, Deleted y Modified. El
primero significa que la fila se ha generado, pero que no es parte de ningún RowsCollection en un DataSet.
Los últimos cuatro indican que la fila no ha sido modificada, que es nueva, que se ha eliminado y que se ha
modificado, respectivamente.
Como parte del RowState, un DataTable conserva tres versiones de cada fila: original, actual y propuesta. El
DataTable utiliza estas versiones para determinar el RowState. La versión original es la fila cuando se agregó
al DataTable. La versión actual es la fila modificada. La versión propuesta existe bajo una condición especial:
cuando se ejecuta el método BeginEdit en la fila.
El método BeginEdit se utiliza para realizar varias modificaciones a las filas sin tener que aplicar reglas de
validación. Por ejemplo, si tiene un grupo de filas que deberán sumar el total de algún valor, se pueden poner
en modo de edición y manejar los valores sin tenter que preocuparse por lo que tendrán que sumar. La fila se
quita del modo de edición y se aplican las reglas de validación cuando se ejecuta el método EndEdit o
AcceptChanges.
El valor original (del origen de datos) se va al DataSet cuando se ejecuta el método Fill. Si haces cualquier
modificación al valor, se convierte en el actual. Entonces se puede regresar al valor original, actualizar el
almacén de datos con el valor actual, o ir al modo edición. En este modo se pueden aceptar las modificaciones
y actualizar el almacén de datos, o cancelar las modificaciones y regresar al valor original o a las versiones
147
actuales.
Pueden ocurrir errores, cada error se almacena en la propiedad RowError del DataRow como una cadena. Se
pueden obtener todos los errores ejecutando el método GetErrors, que devuelve una matriz de DataRows. Si
hay algún error, no se realizarán las actualizaciones al origen de datos.
El DataRow tiene dos métodos: Delete y Remove. Delete destruye totalmente la fila y sus datos y ya no se
puede acceder a ellos. Remove suprime la fila del DataTable para que los datos no puedan ser accedidos por
el programa. El origen de datos real no se modifica.
RejectChanges deshace las modificaciones realizadas desde que se cargó la fila o desde la última vez que
ejecutó AcceptChanges.
Ejemplo:
myConnection = new OleDbConnection("Provider= Microsoft.Jet.OLEDB.4.0;" + "Data
Source=C:\\Inetpub\\wwwroot\\bancario.mdb");
OleDbDataAdapter myCommand = new OleDbDataAdapter("SELECT * FROM tblUsuarios;",
myConnection);
DataSet ds = new DataSet();
myCommand.Fill(ds, "tblUsuarios");
ds.Tables[tblUsuarios2].Rows[0][Nombre]=David;
//hacemos otras cosas
ds.Tables[tblUsuarios2].Rows[0].RejectChanges;
TEMA 10: USO DE XML EN ASP.NET
INTRODUCCIÓN A XML
XML (Lenguaje de Marcado Extensible) es un formato basado en texto para describir datos. Incluye nuevas
formas de distribuir datos a aplicaciones propias de Web, lo que permite que casi cualquier tipo de dato se
envíe a cualquier lugar.
?xml version="1.0" encoding="ISO−8859−1" ?>
<libreria>
<libro genero="novela" estilo="cubierta dura">
<titulo>El cuento de la sirvienta</titulo>
<precio>19.95</precio>
<autor>
<nombre>Margaret</nombre>
148
<apellidos>Atwood</apellidos>
</autor>
</libro>
<libro genero="novela" estilo="rústico">
<titulo>La biblia del bosque de los venenos</titulo>
<precio>11.99</precio>
<autor>
<nombre>Bárbara</nombre>
<apellidos>Kingsolver</apellidos>
</autor>
</libro>
<libro genero="novela" estilo="tapas duras">
<titulo>Aníbal</titulo>
<precio>27.95</precio>
<autor>
<nombre>Richard</nombre>
<apellidos>Harris</apellidos>
</autor>
</libro>
<libro genero="novela" estilo="tapas duras">
<titulo>El péndulo de Focault</titulo>
<precio>22.95</precio>
<autor>
<nombre>Umberto</nombre>
<apellidos>Eco</apellidos>
</autor>
149
</libro>
</libreria>
Esquema:
<Schema
xmlns="urn:schemas−microsoft−com:xml−data"
xmlns:dt="urn:schemas−microsoft−com:datatypes">
<ElementType name="nombre" content="textOnly"/>
<ElementType name="apellido" content="textOnly"/>
<ElementType name="nombrecompleto" content="textOnly"/>
<ElementType name="precio" content="textOnly"
dt:type="fixed.14.4"/>
<ElementType name="autor" content="eltOnly" order="one">
<group order="seq">
<element type="nombrecompleto"/>
</group>
<group order="seq">
<element type="nombre"/>
<element type="apellido"/>
</group>
</ElementType>
<ElementType name="titulo" content="textOnly"/>
<AttributeType name="genero" dt:type="string"/>
<AttributeType name="estilo" dt:type="enumeration"
dt:values="rustico cubiertadura"/>
<ElementType name="libro" content="eltOnly">
<attribute type="genero" required="yes"/>
150
<attribute type="estilo" required="yes"/>
<element type="titulo"/>
<element type="autor"/>
<element type="precio"/>
</ElementType>
<ElementType name="libreria" content="eltOnly">
<element type="libro"/>
</ElementType>
</Schema>
ACCESO A XML MEDIANTE ASP.NET
El acceso a XML es muy similar al acceso a una base de datos mediante ADO.NET. Dos de los objetos más
sencillos XMLTextReader y XMLTextWriter en el espacio de nombres System.XML.
COMO LEER XML
El XMLTextReader es similar a un OleDBDataReader en el sentido que provee un acceso sólo hacia delante.
Para abrir un archivo XML, simplemente hay que generar un XMLTextReader y pasarle el nombre del
archivo XML. Si generamos un archivo LectorXML.aspx y lo colocamos en la misma carpeta que el archivo
XML:
Dim lector as New XMLTextReader (nombreDelArchivoYSuRutaDeAcceso)
XMLTextReader lector = new XMLTextReader (C:\miCarpeta\archivo.xml)
Para acceder a los datos:
Do While (lector.Read())
Hacer algo con los datos
Loop
El método Read avanza automáticamente por el archivo XML siempre que se ejecuta. Hay que cerrar el lector
cuando se termina.
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Xml" %>
<script runat=server>
151
Sub Page_Load(obj As object, e As eventargs)
Dim lector As XmlTextReader
Dim i As integer
Try
lector = new XmlTextReader(Server.MapPath ("libros.xml"))
While lector.Read()
Select Case lector.NodeType
Case XMLNodeType.Element
If lector.HasAttributes Then
For i = 0 To lector.AttributeCount − 1
Response.Write(lector.GetAttribute(i) & " ")
Next
Response.Write("<br>")
End if
Case XMLNodeType.Text
Response.Write(lector.Value & "<br>")
End Select
End While
Catch ex As Exception
Response.Write("Error al acceder el archivo XML.")
Finally
lector.Close
End Try
End Sub
</script>
<html><body>
152
</body></html>
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Xml" %>
<script runat=server>
Sub Page_Load(obj As object, e As eventargs)
Dim lector As XmlTextReader
Try
lector = new XmlTextReader(Server.MapPath ("libros.xml"))
While lector.Read()
Response.Write("<b>" & lector.Name & "</b> " & lector.Value & "<br>")
End While
Catch ex As Exception
Response.Write("Error al acceder el archivo XML.")
Finally
lector.Close
End Try
End Sub
</script>
<html><body>
</body></html>
XMLTextReader tiene la propiedad NodeTyper que indica el tipo de dato que se está buscando:
XMLNodeType.All = todos los nodos
XMLNodeType.Element= Un elemento
XMLNodeType.Document= El nodo principal
ESCRITURA DE XML
El objeto XmlTextWriter ofrece el método Write.
153
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Xml" %>
<script runat=server>
Sub Page_Load(obj As object, e As eventargs)
Dim escritor As XMLTextWriter Se declara un escritor
Try
escritor = new XMLTextWriter(Server.MapPath ("libros2.xml"), Nothing)
Se instancia el escritor, el segundo parámetro es la codificación (predeterminada UTF−8). Si hay un
archivo con el mismo nombre lo sobrescribe.
escritor.WriteStartDocument
escritor.Formatting = Formatting.Indented Indica que sangre el archivo
escritor.Indentation = 3 Que use 3 espacios para el sangrado
escritor.WriteStartElement("libreria") Empieza la generación de datos.Abre la etiqueta de elemento
escritor.WriteStartElement("libro")
escritor.WriteAttributeString("genero", "historia") Genera atributo
escritor.WriteAttributeString("estilo", "cubierta dura")
escritor.WriteElementString("titulo", "Vietnam") Encapsula la funcionalidad de inicio y fin de los
elementos simples.Produce el resultado: <titulo>Vietnam</titulo>
escritor.WriteStartElement("autor")
escritor.WriteElementString("nombre", "Michael")
escritor.WriteElementString("apellido", "Avery")
escritor.WriteEndElement()
escritor.WriteElementString("precio", "6.99")
escritor.WriteEndElement() Cierra la etiqueta de elementos
escritor.WriteEndElement()
escritor.Flush Vacía el contenido
Catch ex As Exception
154
Response.Write("Error al acceder el archivo XML.")
Finally
escritor.Close
Response.Write("Proceso finalizado.")
End Try
End Sub
</script>
<html><body>
</body></html>
Apertura de un archivo XML con XMLDocument e iteración a través del archivo con XMLNodes
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Xml" %>
<script runat=server>
private i As integer
private strResultado As string = ""
Sub Page_Load(obj As object, e As eventargs)
Dim xmldoc As new XMLDocument() Genera un XMLDocument
Try
xmldoc.Load(Server.MapPath("libros.xml")) Carga los datos del archivo XML
MostrarJerarquia(xmldoc.DocumentElement) Itera por los nodos y muestra los datos. DocumentElement
devuelve el primer elemento. Es el punto de inicio para que itere por el archivo.
Catch ex As Exception
strResultado = "Error al acceder el archivo XML."
End Try
resultado.Text = strResultado
End Sub
Sub MostrarJerarquia(nodo As XMLNode)
155
Dim atribnodo As XmlNode
Dim acot As XmlNamedNodeMap Representa colección de atributos de cada nodo
If Not(nodo.HasChildNodes)
strResultado += "  <b>" & nodo.Name & "</b> <" & _ nodo.Value & "><br>" & vbcrlf
Else
strResultado += "<b>" & nodo.Name & "</b>"
If nodo.NodeType = XmlNodeType.Element Then
acot = nodo.Attributes
For Each atribnodo In acot
strResultado += " <b>" & atribnodo.Name & "</b> <" & _ atribnodo.Value & "> " & vbcrlf
Next
End If
strResultado +="<br>"
End If
If nodo.HasChildNodes then
nodo = nodo.FirstChild
While Not IsNothing(nodo)
MostrarJerarquia(nodo)
nodo = nodo.NextSibling Itera por los nodos secundarios de cada nodo
End while
End if
End Sub
</script>
<html><body>
<asp:Label id="resultado" runat="server" />
</body></html>
156
MODIFICACIÓN DE DATOS XML
Para agregar elementos: CreateComment, CreateAttribute, CreateNode, etc.
Cargamos un archivo XML y adjuntamos un nuevo nodo libro.
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Xml" %>
<script runat=server>
Sub Page_Load(obj As object, e As eventargs)
Dim xmldoc As new XMLDocument()
Dim strResultado As String = ""
Try
xmldoc.Load(Server.MapPath("libros.xml"))
Dim eleLibro As XmlElement = xmldoc.CreateElement ("libro")
Dim attEstilo As XmlAttribute = xmldoc.CreateAttribute ("estilo")
eleLibro.SetAttributeNode(attEstilo)
eleLibro.SetAttribute("estilo", "cubierta dura")
Dim root As XmlElement = xmldoc.Item("librería")
root.AppendChild(eleLibro) Obtiene el elemento principal, librería, para que pueda agregarse el nuevo
elemento libro.
xmldoc.Save(Server.MapPath("libros.xml")) Para guardar los cambios
Catch ex As Exception
strResultado = "Error al acceder el archivo XML."
End Try
resultado.Text = "Se terminó adecuadamente la operación de adición."
End Sub
</script>
<html><body>
<asp:Label id="resultado" runat="server" />
157
</body></html>
TEMA 11: LECTURA Y ESCRITURA DE ARCHIVOS EN EL SERVIDOR WEB
USO DE ARCHIVOS CON ASP.NET
Asp.net permite acceder a todo el sistema de archivos del servidor.
INCLUSIÓN DE ARCHIVOS EXTERNOS DESDE EL SERVIDOR
Un archivo incluído desde el servidor es una forma de separar código de una página.
<!−−#include file=../../includes/archivo1.aspx−−>
<!−−#include virtual=/includes/archivo1.aspx−−>
Ejemplo:
Encabezado.aspx
<a href=indice.aspx><img src=encabezado.gif alt=Principal></a><hr>
<a href=indice.aspx>Principal </a> <a href=finSesion.aspx>Finalizar sesión </a>
Página:
<script lenguaje=c# runat=server>
public void Page_Load(object obj, EventArgs e)
{
//hacemos algo
}
</script>
<html><body>
<!−−#include file=Encabezado.aspx−−>
¡Hola a todos!
</body></html>
Asp.net inserta el contenido de Encabezado.aspx antes de procesar cualquier comando.
OLEDB sources
(SQL Server 6.5)
OLE DB .NET
158
Data Provider
DataSet
SQL Server .NET
Data Provider
SQL Server 7.0
(y posterior)
159
Descargar