
05/01/2008 06:55 por
zorry
En el proyecto en el que trabajo actualmente, tenemos que probar cómo se comporta la aplicación web bajo carga de muchos usuarios. Para realizar la carga, empleo Visual Studio 2005 Team Suite.
En una primera aproximación para realizar las pruebas de carga, realicé una captura web mediante la herramienta nativa de Visual Studio. En principio funciona bien, captura las peticiones http a la aplicación, pero como nuestra aplicación funciona con Ajax, las peticiones que realiza la aplicación de manera asíncrona mediante Javascript no son capturadas, con lo que las pruebas no son completas.
La solución que he encontrado ha sido emplear Fiddler para capturar el tráfico. Se arranca esta herramienta de captura antes de arrancar la aplicación web, se realiza la prueba de navegación desde un navegador, y posteriormente, Fiddler permite salvar todo el tráfico entre nuestro navegador y la aplicación web (incluido Ajax) como prueba de Visual Studio.
Posteriormente, este archivo webtest puede importarse en un proyecto de pruebas de Visual Studio 2005 Team suite para realizar las pruebas de carga.
51acd91e-f777-40f4-a0a7-fe91b2742ca8|0|.0

29/12/2007 08:12 por
zorry
Revisando el fix que hice ayer, y debido sobre todo a que no me gusta hacer modificaciones en librerías que no dependen de mí (sobre todo, para evitar que en una nueva release del AjaxControlToolkit me machaquen los cambios), me he fijado en una propiedad del ToolkitScriptManager denominada CombineScriptsHandlerUrl. Esta propiedad permite especificar un handler específico para manejar la combinación de todos los script del AjaxControlToolkit. De modo que me dispongo a deshacer los cambios que hice ayer, y hago varios cambios en mi aplicación web:
- En la definición del ToolkitScriptManager, he incluído el siguiente atributo: CombineScriptsHandlerUrl="~/CombineScriptsHandler.ashx"
- He creado un nuevo handler en la aplicación con el nombre definido en el nombre anterior. En el archivo ashx he introducido el siguiente código:
1: <%@ WebHandler Language="C#" Class="CombineScriptsHandler" %>
2:
3: using System;
4: using System.Web;
5: using AjaxControlToolkit;
6:
7: public class CombineScriptsHandler : IHttpHandler
8: {
9: /// <summary>
10: /// ProcessRequest implementation outputs the combined script file
11: /// </summary>
12: /// <param name="context"></param>
13: public void ProcessRequest(HttpContext context)
14: {
15: if (!ToolkitScriptManager.OutputCombinedScriptFile(context))
16: {
17: throw new InvalidOperationException("Combined script file output failed unexpectedly.");
18: }
19: }
20:
21: /// <summary>
22: /// IsReusable implementation returns true since this class is stateless
23: /// </summary>
24: public bool IsReusable
25: {
26: get { return true; }
27: }
28: }
29:
Con estos cambios por fin he conseguido que la aplicación funcione correctamente en modo cookieless, y sin los problemas de javascript que me estaba encontrando anteriormente.
82354f83-f178-464d-8e98-09ec589bb2f2|0|.0

28/12/2007 15:12 por
zorry
Ok, por fin tengo mi aplicación funcionando en modo cookieless (para que funcione ciertas cosas de la aplicación que la consume). Instalo la última version del AjaxControlToolkit, configuro el tag ToolkitScriptManager correctamente, y pongo el tag CombineScripts a true, para que me combine todos los scripts generados por el toolkit en uno sólo.
Y al cargar la página, me pierde la sesión, en las trazas de IIS, veo que se está llamando a mi página inicial con otro SessionID, con lo que me da un error al cargar los scripts y la página no funciona...
En concreto el problema es que trata de cargar el script sin poner delante el SessionID:
/WebApp/Resumen.aspx?_TSM_HiddenField_=ctl00_scriptManager_HiddenField&_TSM_CombinedScripts_=%3b%3bAjaxControlToolkit%2c+Version%3d1.0.11119.32029%2c+Culture%3dneutral%2c+PublicKeyToken%3d28f01b0e84b6d53e%3aes-ES%3a2d550902-56f7-46bd-9795-b930029c9f3f%3ae2e86ef9%3a9ea3f0e2%3a9e8e87e9%3a1df13a87%3a80f47b59%3ad7738de7
Tenemos que lograr que el AjaxControlToolkit renderice la siguiente llamada para asegurarnos que no se pierde la sesión:
/WebApp/(S(w4fcmx45goyog355ydy4rw3w))/Resumen.aspx?_TSM_HiddenField_=ctl00_scriptManager_HiddenField&_TSM_CombinedScripts_=%3b%3bAjaxControlToolkit%2c+Version%3d1.0.11119.33116%2c+Culture%3dneutral%2c+PublicKeyToken%3d28f01b0e84b6d53e%3aes-ES%3af5528113-d4f3-4bcc-99aa-dc1a40d76a47%3ae2e86ef9%3a9ea3f0e2%3a9e8e87e9%3a1df13a87%3a80f47b59%3ad7738de7
Para ello, abrimos el código del AjaxControlToolkit... En concreto tocamos en la clase ToolkitScriptManager.cs... (Tengamos en cuenta que estoy trabajando con la release del 19 de Noviembre de 2007). La línea a modificar es la 144, y la reemplazaremos dejando el siguiente código:
144: _combinedScriptUrl = String.Format(CultureInfo.InvariantCulture,
145: "{0}?{1}={2}&{3}={4}", ((null != _combineScriptsHandlerUrl) ? _combineScriptsHandlerUrl.ToString()
146: : (new Uri(Page.Request.Url, Page.Request.RawUrl)).AbsolutePath)
147: , HiddenFieldParamName, HiddenFieldName, CombinedScriptsParamName,
148: HttpUtility.UrlEncode(SerializeScriptEntries(_scriptEntries, false)));
El código modificado se encuentra en la línea 146. De esta manera, se parsea la Url de la petición haciendo que se solicite la Url del script con el id de sesión, funcionando así correctamente la llamada Cookieless.
b3b7c0b1-e88d-463b-be94-01fe639b59ee|0|.0

03/06/2007 19:06 por
zorry
Bueno, tras una gran pausa, sigamos con este pequeño tutorial acerca de cómo usar las extensiones Ajax en .Net.
Partimos de una versión modificada de la demo del artículo anterior. Recordemos que en el artículo anterior vimos como realizar actualizaciones parciales de la página mediante el control UpdatePanel, evitando realizar postbacks completos del cliente al servidor, evitando el redibujado completo del navegador en cada cambio de la página.
En esta demo, en lugar de realizar la carga de un DropDownList desde otro, lo que hacemos es realizar la carga de un GridView dependiendo de la selección desde un DropDownList:
Lo que ocurrirá es que el usuario no sabrá si debe esperar para trabajar con la página, si la carga del grid inferior tarda más de lo normal (por ejemplo, si la base de datos está sobrecargada, o la consulta es compleja o trae muchos datos). Para ello, emplearemos el control UpdateProgress que nos facilita las extensiones Ajax. Para ello, en la página maestra, introduciremos el siguiente código:
<asp:UpdateProgress ID="UpdateProgress1" runat="server" >
<ProgressTemplate>
<div class="progress">
<asp:Image ID="Image1" runat="server"
ImageUrl="~/images/indicator_mozilla_blu.gif"/>
Actualizando página
</div>
</ProgressTemplate>
</asp:UpdateProgress>
Mediante este control, conseguimos que el HTML que está dentro del ProgressTemplate se muestre cuando las extensiones Ajax detecten que hay una llamada asíncrona al servidor. Dentro del template se puede poner cualquier código HTML ya que en cliente se renderiza con un DIV oculto. En este caso, estoy mostrando un DIV con una imagen animada y un texto indicando al usuario que la página se está actualizando. Este DIV tira de una clase llamada progress, que contiene cualquier decoración CSS que se nos ocurra. En nuestro caso, quería que se mostrara sobre los controles que están siendo actualizados, por lo que la clase progress queda en el ejemplo asi:
.progress
{
border-right: #ff6633 thin solid;
border-top: #ff6633 thin solid;
vertical-align: middle;
border-left: #ff6633 thin solid;
border-bottom: #ff6633 thin solid;
position: absolute;
background-color: #ffcc66;
text-align: center;
padding: 10px;
left: 100px; top: 100px;
}
Tras aplicar esto, y cambiar de selección en el DropDownList, podremos ver el siguiente efecto:
Esto es todo, hasta la siguiente entrega del tutorial.
f7a21ad3-47d5-42eb-8dba-be6c73120a94|0|.0

26/03/2007 05:03 por
zorry
A continuación veremos un primer ejemplo de implementación mediante el framework de Microsoft de AJAX. Para verlo, crearemos un "ASP.NET AJAX-Enabled website" en Visual Studio 2005, y lo denominaremos Ejemplo. Esta plantilla de Visual Studio nos generará un sitio Web, con un archivo Web.config con las modificaciones necesarias para que Ajax.Net funcione correctamente, así como una página default.aspx, la cual incluirá una referencia al control ScriptManager. Recordemos que en el artículo anterior vimos que el ScriptManager es el control necesario para que Ajax.pueda funcionar.
Incluimos el control ScriptManager
Es necesario incluir un control ScriptManager en cada página que vaya a emplear AJAX. En caso de una aplicación que emplee páginas maestras, lo ideal es incluirlo en la página maestra, evitando de esta manera tener que incluirlo en todas las páginas.
Eliminaremos la página default.aspx de la solución, y crearemos una página maestra denominada "master.master". Dentro de esta página, justo encima del control ContentPlaceHolder, incluiremos la siguiente línea:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
Es importante especificar el atributo EnablePartialRendering, ya que es el que nos permitirá realizar modificaciones parciales de las páginas.
Empleamos el control UpdatePanel
Crearemos una página que emplee la página maestra que acabamos de crear, añadimos una "Web Content Form" llamada "default.aspx". Dentro de ésta página, vamos a crear dos controles DropDownList encadenados, de manera que cuando seleccionemos un valor del primero, cargue los valores del segundo. Para ello, empleamos el siguiente código, dentro de la página:
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:DropDownList ID="ddl" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddl_SelectedIndexChange">
<asp:ListItem Text="Email" Value="1" />
<asp:ListItem Text="Telefono" Value="2" />
</asp:DropDownList>
<asp:UpdatePanel ID="updatePanel" runat="server">
<ContentTemplate>
<asp:DropDownList ID="ddl2" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
Adicionalmente, en el archivo default.aspx.cs incluiremos el siguiente código:
protected void ddl_SelectedIndexChange(object sender, EventArgs e)
{
ddl2.Items.Clear();
if (ddl.SelectedValue == "1")
{
ddl2.Items.Add(new ListItem("Valor 1", "1"));
ddl2.Items.Add(new ListItem("Valor 2", "2"));
}
else
{
ddl2.Items.Add(new ListItem("Valor 3", "3"));
ddl2.Items.Add(new ListItem("Valor 4", "4"));
}
}
De esta manera podremos ver cómo, al seleccionar un valor en el desplegable, el segundo desplegable cambia de valor. Pero en este caso, la actualización se está haciendo mediante un postback completo, en lugar de emplear Ajax para redibujar el segundo desplegable. Esto es así, porque el UpdatePanel no sabe que tiene que redibujarse al cambiar el primer desplegable (el primer desplegable está fuera del UpdatePanel). Para modificar la página y conseguir que se emplee Ajax, existen dos posibilidades:
- Introducir el primer desplegable dentro del UpdatePanel. De esta manera el UpdatePanel realizará las llamadas por Ajax a todos los eventos de servidor que se produzcan en su interior.
- Modificar el UpdatePanel, introduciendo un trigger configuranod el UpdatePanel para que "escuche" los eventos realizados por el desplegable. Ésta es la mejor manera desde mi punto de vista, puesto que para que las recargas sean óptimas, los UpdatePanel deberían ser lo más pequeños posibles.
Por tanto, la solución sería la siguiente, modificar el UpdatePanel introduciendo este código (antes o después del tag ContentTemplate):
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddl" EventName="SelectedIndexChanged" />
</Triggers>
1324c9e6-a239-48d6-a710-611b36fb4e94|0|.0

26/03/2007 04:03 por
zorry
En el proyecto en que estoy trabajando actualmente, he tenido la oportunidad de empezar a trabajar en un proyecto de manera seria con Ajax, y en concreto con las extensiones Ajax de Microsoft. Ciertamente me ha parecido muy instructivo y a partir de mi experiencia, quiero compartir una serie de artículos que ayuden a los que estén iniciándose en esta tecnología a empezar lo más rápido posible.
¿Que es Ajax?
Ajax es el acrónimo de Asynchronous Javascript And XML. Esta tecnología de desarrollo web, se basa en dos puntos fundamentales:
- Realizar comunicaciones asíncronas entre el navegador del cliente y el servidor. Se realizan mediante javascript y llamadas asíncronas en segundo plano, realizando intercambios de datos en formato XML entre el cliente y servidor.
- Evitar el refresco completo de la página, recargando únicamente las partes modificadas de la aplicación, consiguiendo así aplicaciones más rápidas y más cercanas a las aplicaciones de escritorio.
Mediante esta técnica podremos, por ejemplo, cargar los elementos de un desplegable desde base de datos, sin necesidad de recargar la pantalla completa, sino recargando únicamente la parte de la página afectada por el cambio (en el ejemplo, recargando los elementos del desplegable), sin necesidad de recargar la página completa.
¿Que proporcionan las extensiones Asp.Net Ajax?
Estas extensiones (actualmente en versión 1.0), desarrolladas por Microsoft, permiten integrar los desarrollos realizados en ASP.NET 2.0 con ésta tecnología de desarrollo de una manera fácil e intuitiva. Es necesario remarcar que esta tecnología, aún estando desarrollada por Microsoft explícitamente para ASP.NET, debería ser compatible con diferentes navegadores de otros fabricantes, como por ejemplo, Mozilla, o Opera. No obstante, como la aplicación en la que estoy trabajando, no es multinavegador, no he tenido la oportunidad de comprobarlo por mi mismo :-)
Además, este framework abstrae al desarrollador el desarrollo necesario para implementar las llamadas asíncronas de Javascript al servidor, de manera que el desarrollador puede centrarse en cómo debe funcionar su aplicación, y no perder tiempo en escribir (una y otra vez) rutinas Javascript para llamar al servidor y redibujar el contenido de la página.
Internamente el framework emplea el objeto XMLHttpRequest, disponible en casi todos los navegadores modernos, para realizar la comunicación entre cliente y servidor. De esta manera, aprovechando que en ASP.NET 2.0 se introduce el concepto de Callback, el navegador llama al servidor para obtener la versión actualizada de la página mediante javascript, y posteriormente, mediante DHTML, se muestra la nueva versión de la página al cliente.
El framework de ASP.NET Ajax se basa en cuatro partes bien diferenciadas:
- ASP.NET AJAX Extensions: El núcleo de la implementación de AJAX. Proporciona un pequeño núcleo de controles de servidor que permiten realizar la mayor parte de las operaciones cliente / servidor. http://www.microsoft.com/downloads/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&displaylang=en
- ASP.NET AJAX Library: Es un conjunto de librerías y de clases Javascript que facilitan el trabajo del desarrollador en el navegador cliente. Además, facilitan una serie de métodos y patrones para realizar llamadas a servidor directamente desde Javascript. Estas librerías se distribuyen dentro de ASP.NET AJAX Extensions.
- ASP.NET AJAX Control Toolkit: Una serie de controles que, basandose en las extensiones AJAX, expanden la funcionalidad de los controles y proveen al desarrollador de controles ricos que pueden usar en la aplicación (por ejemplo, un control de selección de fecha, un control que permite tener múltiples pestañas en la aplicación, etc). Este toolkit se ha creado y se mantiene entre Microsoft y la comunidad de codeplex, y por tanto, es de código abierto y cualquiera que quiera contribuir con el desarrollo puede hacerlo. http://www.codeplex.com/AtlasControlToolkit
- ASP.NET AJAX Futures: Nuevas funcionalidades que se incluirán en subsiguientes implementaciones del framework. Actualmente se encuantra en versión CTP, y la última versión es de Enero de 2007. http://www.microsoft.com/downloads/details.aspx?FamilyID=4cb52ea3-9548-4064-8137-09b96af97617&displaylang=en
Las extensiones Ajax facilitan básicamente cuatro controles:
- ScriptManager: Uno de los dos controles principales del framework. Es el control que provee a la página de la funcionalidad de cliente, como por ejemplo, realizar las llamadas asíncronas al servidor, realizar el redibujado parcial de páginas, etc... Este control es necesario para realizar cualquier operación con el framework.
- UpdatePanel: El otro control principal del framework. Es un control que hereda del control Panel de Asp.Net. Además de las funcionalidades propias de un Panel, todos los controles que se encuentren dentro de él podrán ser modificados sin necesidad de realizar un postback, sino que se modificarán en cliente mediante llamadas Callback.
- UpdateProgress: Este control permite presentar a un cliente un aviso informándole de que el navegador está ocupado realizando una modificación asíncronamente.
- ScriptManagerProxy: Este control se emplea en caso de que el ScriptManager se encuentre en otra página, por ejemplo, en una página maestra, y se necesite acceder a las propiedades del mismo ScriptManager. Por ejemplo, incluir un javascript en una página y que el ScriptManager de la página maestra lo cargue en el cliente.
En el siguiente artículo veremos como implementar un pequeño ejemplo, empleando únicamente las extensiones de ajax.
35aa2173-4547-4351-bf28-7a8a4affc565|0|.0