Software y Aplicaciones Web

Blog de desarrollo de software y aplicaciones web

Comentarios Recientes

Comment RSS

MSDN Home Page (Argentina)


C# Corner


AspAlliance.com

Declaración

Las opiniones en este blog se proporcionan "TAL CUAL", sin garantías,  no confieren derechos y no reflejan, necesariamente, la opinión de quienes me contratan.
Algunas cuestiones que se comentan en el blog no son reales, cualquier similitud con alguna persona viva o muerta no es más que una coincidencia, tampoco significa que necesite terapia, soy asi.

© Copyright 2007-2010

Propaganda

Este sitio implementa publicidad basada en intereses
Jun
29.
2008

  Un Poco de AJAX

Indudablemente AJAX es una de las tecnologías que mejoran la satisfacción del usuario (menos mal, porque sino no nos pagan ...), de manera que esta publicación pretende mostrar un ejemplo de cómo se puede utilizar.

Simpre que desarrollo una aplicación me ha preocupado mantener una especie de diálogo con el usuario final, avisarle que está ocurriendo y por supuesto cuando las cosas no funcionan indicarle de una manera razonable que lamentablemente debe llamarme para arreglar el problema ...

Por otro lado, mi participación en las Celulas Académicas de Microsoft (Jujuy ASP NET y THE ASP-BERRIES) me enseñan que es importante mostrar algunos aspectos del desarrollo, los que a veces nos parecen trivales.

Bien, la idea es contar con un mecanismo que nos permitma mostrar mensajes en una aplicación WEB.

Cuando desarrollamos para escritorio siempre podremos utilizar el MsgBox. Pero resulta que en el desarrollo de aplicaciones WEB no existe, si bién hay bastantes ejemplos sobre cómo armar una ventana modal que muestre mensajes, ocurre que mi ego y preferencias personales me llevaron a escribir el siguiente código. Obviamente le copie la idea a la gente de Gmail (no se cómo será el código que utilizan pero esta es la implementación que se me ocurrió).

 

Una aplicación WEB seguramente tiene una Master Page (al menos en el mundo de ASP NET así es ...), además se incorpora una hoja de estilo que nos permite cambiar la presentación de forma rápida y elegante. A todo esto, la programción orientada a objetos nos brinda la posibliad de hacer que todas las páginas de la aplicación sean derivadas o hereden propiedades y métodos de alguna clase base que implementa el comportamiento común que deseamos para la aplicación.

Crear el proyecto y solucionLo primero es crear un proyecto, y como vamos a utilizar AJAX entonces en el Visual Studio 2008, utilizamos File-New-Project... y en las opciones elegimos Visual C# para ver todas las plantillas disponibles de las cuales marcamos AJAX 1.0-Enabled ASP.NET 2.0 W...

Bueno hay que darle un nombre e indicar si se va a crear una solución para este proyecto. Cuando está todo listo tendrán un proyecto que incorpora todo lo necesario para desarrollor un sitio web que cuenta con las extensiones AJAX que ya vienen en el Microsoft Framework 3.5.

Recuerden que para el Framework 2.0 hay que bajarse las extensiones e instalarlas, todo esto se puede ver mejor en la página oficial de AJAX.

 

Con el proyecto en la mano, vamos a incorporar una master page que debe contener al menos lo siguiente:

  • Un control <asp:ScriptManager ... />, este control es imprecindible si vamos a utilizar comunicación asincrónica con el servidor.
  • Un control <asp:UpdatePanel> ... </asp:UpdatePanel>, nos permitirá mostrar los mensajes sin recargar toda la página (a esto es lo que le llaman mayor satisfacción del usuario final).
  • Un contenedor simple <div> ... </div> al que le asignaremos una clase de la hoja de estilo (más adelante detallamos como es el estilo).
  • Un control <asp:Label> ... </asp:Label> que utilizaremos para mostrar los mensajes, es posible utilizar otro tipo de control pero por ahora quiero mantener las cosas lo más simples posibles.
  • Un control <asp:Timer> ... </asp:Timer>, con el que controlaremos el tiempo que se muestran los mensajes.

A continuación está el código de la master page, observen que yá está haciendo referencia a una hoja de estilo, mas adelante voy a explicar lo que haga falta sobre ella.

Es importante destacar que el control Label tiene el ViewState en False, de ese modo no tenemos que borrar los mensajes dado que esa información solamente viene del servidor se muestra en el browser del cliente y no vuelve al servidor en el siguiente postback se o no asincrónico.

La otra cuestión importante es que al control UpdatePanel hay que indicarle que tiene un "gatillo" trigger que lo relaciona con el control Timer, de esta manera es como se logra que el timer se ejecute de acuerdo al intervalo que le indicamos (en este ejemplo es 10000 milisegundos) y entonces es atrapado por el trigger del UpdatePanel que lo fuerza a realizar el postback asincrónico.

Las otras cosas que están en la master page son las que corresponden a la aplicación y no tienen nada que ver con el esquema de Mensajes.

 

Listado 1: MasterPage.master

   1:  <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MasterPage.master.cs" Inherits="AJAXDemo30.MasterPage" %>
   2:   
   3:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   4:   
   5:  <html xmlns="http://www.w3.org/1999/xhtml" >
   6:  <head runat="server">
   7:    <title>AJAX Demo in MS Framework 3.0</title>
   8:    <link href="Styles/SiteStyle.css" rel="stylesheet" type="text/css" />
   9:    <asp:ContentPlaceHolder ID="head" runat="server">
  10:    </asp:ContentPlaceHolder>
  11:  </head>
  12:  <body>
  13:    <form id="form1" runat="server">
  14:    <asp:ScriptManager ID="ScriptManager1" runat="server" />
  15:    <div>
  16:      <div id="center">
  17:        Aqu&iacute; deber&iacute;a estar el t&iacute;tulo y men&uacute; de la aplicaci&oacute;n
  18:        <hr />
  19:        <asp:UpdatePanel id="updpnlMsg" runat="server" UpdateMode="Conditional" >
  20:          <ContentTemplate>
  21:            <div class="divMsg">
  22:              <asp:Label id="lblMsg" runat="server" EnableViewState="False" CssClass="lblMsg"></asp:Label>        
  23:            </div>
  24:          </ContentTemplate>
  25:          <Triggers>
  26:            <asp:AsyncPostBackTrigger ControlID="timerMsg" />
  27:          </Triggers>
  28:        </asp:UpdatePanel>
  29:        <asp:Timer ID="timerMsg" runat="server" Interval="10000" >
  30:        </asp:Timer>
  31:        <hr />
  32:        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
  33:          ... En este lugar puede estar algo que siempre queremos que est&eacute;
  34:        </asp:ContentPlaceHolder>
  35:        <hr />
  36:        Aqu&iacute; deber&iacute; estar el pi&eacute; de p&aacute;gina, siempre es bueno hacer un poco de propagana
  37:      </div>
  38:    </div>
  39:    </form>
  40:  </body>
  41:  </html>

 

El código asociado a la Master Page no tiene nada, solamente lo que el Visual Studio le pone, de manera que no lo muestro.

Ahora veamos como funciona una página de la aplicación. Para ello vamos a borrar la que puso el Visual Studio cuando creamos el proyecto, resulta que está no utiliza Master Page.

Agregamos una página que utilice Master Pages, se hace con Add-New Item ... y elegimos Web Content Form, le damos el nombre Default.aspx (esto no es necesario, pero normalmente esta es la página de inicio de un sitio web) y luego le indicamos que página maestra queremos asociarle.

Observern que le puse algo de texto, y un par de botones que serviran para utilizar el esquema de mensajes. A continuación está el código de la página.

 

Listado 2: Default.aspx

   1:  <%@ Page Language="C#" MasterPageFile="~/MasterPage.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AJAXDemo30.Default" Title="AJAX Demo in MS Framework 3.0" %>
   2:  <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
   3:  </asp:Content>
   4:  <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
   5:    <asp:UpdatePanel id="upnl1" runat="server" >
   6:      <ContentTemplate>
   7:        <p>
   8:          Esta es la página por defecto del Demo de AJAX en MS Framework 3.0
   9:          <br />
  10:          Vamos a probar como funciona el esquema de mensajes
  11:        </p>
  12:        <p>
  13:          El Mensaje Normal muestra un texto durante un tiempo (en este caso es de 10 
  14:          segundos) y luego desaparace.
  15:        </p>
  16:        <p>
  17:          En cambio el Mensaje Crítico&nbsp; muestra un texto que debe estar en pantalla mucho 
  18:          m&aacute;s tiempo (ahora lo hace por una hora).
  19:        </p>
  20:        <p>
  21:          Por supuesto, si el usuario realiza alguna operaci&oacute;n que implique un mensaje, 
  22:          este mensaje es reemplazado por el otro y seguramente cambia la duraci&oacute;n establecida
  23:        </p>
  24:        <p>
  25:          Sirve para mostrar los mensajes de error cuando las cosas no funcionan bien.
  26:        </p>
  27:        <div class="right">
  28:          <asp:Button ID="btnMsgNormal" runat="server" Text="Mensaje Normal" onclick="btnMsgNormal_Click" />
  29:          &nbsp;
  30:          <asp:Button ID="btnMsgCritial" runat="server" Text="Mensaje Cr&iacute;tico" onclick="btnMsgCritial_Click" />
  31:        </div>
  32:      </ContentTemplate>
  33:    </asp:UpdatePanel>
  34:  </asp:Content>

 

El código asociado a la página es el siguiente. Simplemente se invoca a un par de metodos MsgSet() y MsgSetCritical() que nos permite enviar mensajes.

Observen que la clase deriva de PageBase, es en esa clase donde vamos a poner el código del esquema de mensajes. 

 

Listado 3: Default.aspx.cs

   1:  using System;
   2:   
   3:  namespace AJAXDemo30
   4:  {
   5:    public partial class Default : PageBase
   6:    {
   7:      protected void Page_Load(object sender, EventArgs e)
   8:      {
   9:      }
  10:   
  11:      protected void btnMsgNormal_Click(object sender, EventArgs e)
  12:      {
  13:        MsgSet("Este mensaje deber&iacute;a desaparecer en 10 segundos !!!");
  14:      }
  15:   
  16:      protected void btnMsgCritial_Click(object sender, EventArgs e)
  17:      {
  18:        MsgSetCritical("Este es un mensaje cr&iacute;tico se mantiene <b>durante una hora</b>");
  19:      }
  20:   
  21:    }
  22:  }

 

Bueno veamos entonces como es la clase base que implementa el esquema de mensajes. En este ejercicio incorporé la clase directamente en la carpeta raíz del sitio web, esta clase debería estar en un directorio de clases o mejor aún en un dll probablemente en otro proyecto para que de ese modo se pueda reutilizar desde todos los proyectos que queramos.

Hay unos campos privados para referenciar a los controles que se supone existen en la master page de la instancia de página que está ejecutando los métodos.

La propiedad MsgIsOk se utiliza para asegurarse que existen los controles. El método MsgSetTimer sirve para fijar el intervalo del control Timer para que se dispare el postback asincrónico en el Update Panel. El método MsgShow es el encargado de actualizar el Update Panel.

Los métodos MsgSet y MsgSetCritical que se pueden heredar simplemente le dan formato al mensaje y ajustan el valor del timer según sea un mensaje común (10 segundos) o un mensaje crítico (1 hora).

 

Listado 4: PageBase.cs

   1:  using System;
   2:  using System.Web.UI;
   3:  using System.Web.UI.WebControls;
   4:   
   5:  namespace AJAXDemo30
   6:  {
   7:    /// <summary>
   8:    /// Clase base para todas las páginas
   9:    /// </summary>
  10:    public abstract class PageBase : System.Web.UI.Page
  11:    {
  12:   
  13:      #region Messages
  14:   
  15:      /// <summary>
  16:      /// Reference to Label lblMsg in Master Page
  17:      /// </summary>
  18:      private Label _lblMsg;
  19:      /// <summary>
  20:      /// Reference to Timer timerMsg in Master Page
  21:      /// </summary>
  22:      private Timer _timerMsg;
  23:   
  24:      /// <summary>
  25:      /// Test if exist reference for lblMsg in Master Page
  26:      /// also it test if exist reference for timerMsg in Master Pager too
  27:      /// </summary>
  28:      private Boolean MsgIsOk
  29:      {
  30:        get
  31:        {
  32:          this._lblMsg = (Label)this.Master.FindControl("lblMsg");
  33:          this._timerMsg = (Timer)this.Master.FindControl("timerMsg");
  34:          return (this._lblMsg != null);
  35:        }
  36:      }
  37:      /// <summary>
  38:      /// Set timer interval in miliseconds
  39:      /// </summary>
  40:      /// <param name="interval"></param>
  41:      private void MsgSetTimer(int interval)
  42:      {
  43:        if (this._timerMsg != null)
  44:        {
  45:          _timerMsg.Interval = interval;
  46:        }
  47:      }
  48:      /// <summary>
  49:      /// Shows messages with partial postback
  50:      /// </summary>
  51:      private void MsgShow()
  52:      {
  53:        UpdatePanel updpnlMsg = (UpdatePanel)this.Master.FindControl("updpnlMsg");
  54:        if (updpnlMsg != null)
  55:        {
  56:          updpnlMsg.Update();
  57:        }
  58:      }
  59:      /// <summary>
  60:      /// Show a message
  61:      /// </summary>
  62:      /// <param name="msg">Message text to put in Label control.</param>
  63:      protected void MsgSet(string msg)
  64:      {
  65:        if (MsgIsOk)
  66:        {
  67:          MsgSetTimer(10000);
  68:          _lblMsg.Text = "&nbsp;" + msg + "&nbsp;";
  69:          MsgShow();
  70:        }
  71:      }
  72:      /// <summary>
  73:      /// Show a message preceded with critial error 
  74:      /// </summary>
  75:      /// <param name="msg">Message text to put in Label control</param>
  76:      protected void MsgSetCritical(string msg)
  77:      {
  78:        if (MsgIsOk)
  79:        {
  80:          MsgSetTimer(3600000);
  81:          _lblMsg.Text = "&nbsp;" + string.Format("Error cr&iacute;tico: {0}", msg) + "&nbsp;";
  82:          _lblMsg.ForeColor = System.Drawing.Color.Red;
  83:          MsgShow();
  84:        }
  85:      }
  86:   
  87:      #endregion
  88:   
  89:    }
  90:  }

 

Por último comentamos un poco de la hoja de estilo, en body tiene lo mínimo para una página de 800x600. Hay una clase .right que permite poner los controles a la derecha.

El estilo para el esquema de mensajes básicamente establece un área minima min-height de manera que la página no esté cambiando de tamaño a cada rato, utilizar min-heght permite que se muestren grandes bloques de texto dado que se establece el mínimo.

Listado 5: SiteStyle.css

   1:  body {
   2:    font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif;
   3:    font-size:12px;
   4:    margin:0;
   5:    padding:0;
   6:    width:780px;
   7:  }
   8:  /* Esto es el para el contenedor principal */
   9:  #center {
  10:    position:relative;
  11:    width:100%;
  12:  }
  13:  .right {
  14:    float: right;
  15:  }
  16:   
  17:  /* Esquema de Mensajes */
  18:  .divMsg {
  19:    width: auto;
  20:    min-height: 20px;
  21:    text-align: center;
  22:  }
  23:  .lblMsg {
  24:    background: #CCFF99;
  25:    color: #000000;
  26:    font-size: 1.1em;
  27:  /*    font-weight: bold;*/
  28:  }

 

Bien, después de realizar el ejercicio quede bastante conforme con el resultado y lo estoy utilizando. Sin embargo siempre vuelvo a pensar que debería implementar un mecanismo que active y desactive el timer dado que una vez que se borra un mesaje no hace falta estar disparando el autoposback del Update Panel a cada rato dado que no hay nada para borrar y es una acción innecesaria, pero eso lo dejo para otra publicación.

Auí está el proyecto completo para que se lo bajen AJAXDemo30.zip (12,48 kb), si lo pueden mejorar me avisan.

Espero que les sirva




Categorías: ASP.NET | Celulas | Programacion | WebSite



Comments (6) -

green Colombia

Thursday, February 12, 2009 8:07 AM

green

Holaa, Como se pondria hacer aparecer ese mensaje en frente de la página y que se desabilite el fondo, estilo facebook.
gracias.

Julio Tentor Argentina

Friday, February 13, 2009 8:33 PM

Julio Tentor

En el post de Mads, aprendemos como deshabilitar toda la página y poner por arriba un nuevo formulario, tendríamos que trabajar esta técnica con lo de los mensajes, apenas tenga un poquito de tiempo lo intento.

Julio Tentor Argentina

Friday, February 13, 2009 9:17 PM

Julio Tentor

Te recomiendo que veas este post blog.madskristensen.dk/.../...tBox-JavaScript.aspx

Pedro Argentina

Saturday, September 19, 2009 3:41 PM

Pedro

Buen dia ingeniero, me baje e instale el Visual Web Developer 2008 express y en el puedo crear formularios web y trabajar como si tuviera el visual estudio 2008, con la unica diferencia que no puedo crear soluciones, solo crear proyectos, ese es el unico inconveniente que pude ver, habra aulgun otro? o podre trabajar tranquilo con esta version express?, de todos modods seguire trabajando, y cualquier consulta o inconveniente se lo arè saber,,gracias y buen fin de semana...@(>_<)@

Pedro Argentina

Saturday, September 19, 2009 3:54 PM

Pedro

Buenisimo, me permite configurar directamente desde mi proyecto el IIS en propiedades de la pagina q estoy creando,,,Buenisimo, pude crear la carpeta virtual

jtentor Spain

Saturday, September 19, 2009 5:25 PM

jtentor

Pedro, La verdad es que no probé la versión Express y no puedo decir si se puede o no trabajar con soluciones, debería poderse. Fijate bien en Otros projectos - Soluciones Visual Studio (no hay que elegir lenguaje, eso se hace despues para un proyecto en particular).
Me parece espectacular, que estés verificando que se puede hacer todo lo que dice el libro.

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading