¿Qué hay debajo de Atlas?

Antes de leer: Recomiendo la descarga del código fuente para poder ver el código más cómodamente: Descárgalo aquí


En este artículo vamos a ver cómo funciona Atlas por debajo, analizando el código HTML que se genera en ejecución de un sencillo ejemplo:




 


 Que hay debajo de Atlas - Figura 1


 


Para quien aún no sepa que es Atlas, es la tencología de Microsoft para impplementar la metodología AJAX (Asynchronous JavaScript and XML). Destaco metodología ya que en numerosas webs lo confunden con una nueva tecnología, cuando se trata de la metodología de uso de unos estándares que llevan tiempo usandose.


 


Ahora, sin mas explicación, vamos a ver el código en modo de diseño de nuestro ejemplo:


 








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<%@ Page Language=»VB» AutoEventWireup=»false» CodeFile=»Default.aspx.vb» Inherits=»_Default» %>

<%@ Register Assembly=»Microsoft.Web.Atlas» Namespace=»Microsoft.Web.UI.Controls»
TagPrefix=»cc2″ %>

<%@ Register Assembly=»Microsoft.Web.Atlas» Namespace=»Microsoft.Web.UI» TagPrefix=»cc1″ %>

<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Transitional//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd»>

<html xmlns=»http://www.w3.org/1999/xhtml» >
<head id=»Head1″ runat=»server»>
<title>Ejemplo de Atlas</title>
</head>
<body>
<form id=»form1″ runat=»server»>
<cc1:ScriptManager ID=»ScriptManager1″ runat=»server» EnablePartialRendering=»True»>
<ErrorTemplate>
<div style=»border-right: #000000 1px solid; padding-right: 12px; border-top: #000000 1px solid;
padding-left: 12px; padding-bottom: 12px; border-left: #000000 1px solid; width: 400px;
padding-top: 12px; border-bottom: #000000 1px solid; height: 140px; background-color: white;
text-align: left»
>
Ha ocurrido un error.
<asp:LinkButton ID=»okButton» runat=»server»>Aceptar</div>
</ErrorTemplate>
</cc1:ScriptManager>
<cc2:TimerControl ID=»TimerControl1″ runat=»server» Interval=»1000″>
</cc2:TimerControl>
<cc1:UpdatePanel ID=»UpdatePanel1″ runat=»server»>
<ContentTemplate>
</asp:Label ID=»Label1″ runat=»server»>
</ContentTemplate>
</cc1:UpdatePanel>
</form>
</body>
</html>
 


Y el código de servidor:



 







1
2
3
4
5
6
7
Partial Class _Default
Inherits System.Web.UI.Page

Protected Sub TimerControl1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles TimerControl1.Tick
Label1.Text = Now.ToString()
End Sub
End Class
 



 


Las directivas es lo primero que tenemos que ver:


 








1
2
3
4
<%@ Page Language=«VB» AutoEventWireup=«false» CodeFile=«Default.aspx.vb» Inherits=«_Default» %>
<%@ Register Assembly=«Microsoft.Web.Atlas» Namespace=«Microsoft.Web.UI.Controls»
TagPrefix=«cc2» %>
<%@ Register Assembly=«Microsoft.Web.Atlas» Namespace=«Microsoft.Web.UI» TagPrefix=«cc1» %>
 


 


Como podéis observar hay tres directivas, la directiva Page y dos directivas Register. Las directivas Register son las que registran los namespace para que puedan ser usados en la página.


 


Lo siguiente que debemos ver es el control ScriptManager:


 







1
2
3
4
5
6
7
8
9
10
        <cc1:ScriptManager ID=»ScriptManager1″ runat=»server» EnablePartialRendering=»True»>
<ErrorTemplate>
<div style=»border-right: #000000 1px solid; padding-right: 12px; border-top: #000000 1px solid;
padding-left: 12px; padding-bottom: 12px; border-left: #000000 1px solid; width: 400px;
padding-top: 12px; border-bottom: #000000 1px solid; height: 140px; background-color: white;
text-align: left»
>
Ha ocurrido un error.
<asp:LinkButton ID=»okButton» runat=»server»>Aceptar</div>
</ErrorTemplate>
</cc1:ScriptManager>
 


 


El control ScriptManager es el encargado de enviar al cliente el Framework necesario para que la aplicación funcione. Tiene una plantilla configurable, ErrorTemplate, que es la que se mostraría en caso de error con algún control de Atlas. En nuestro caso se mostraría así la página:


 



Que hay debajo de Atlas - Figura2


 


El control con el ID okButton es el encargado de cerrar el mensaje de error.


 








1
2
<cc2:TimerControl ID=»TimerControl1″ runat=»server» Interval=»1000″>
</cc2:TimerControl>


 


El control TimerControl1 lo hemos configurado para un intervalo de un segundo. Gestionamos su evento Tick con el siguiente código de servidor:









1
2
3
    Protected Sub TimerControl1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles TimerControl1.Tick
Label1.Text = Now.ToString()
End Sub


 


Lo que nos queda por ver de nuestro código es el UpdatePanel:


 








1
2
3
4
5
        <cc1:UpdatePanel ID=»UpdatePanel1″ runat=»server»>
<ContentTemplate>
</asp:Label ID=»Label1″ runat=»server»>
</ContentTemplate>
</cc1:UpdatePanel>


 


El ContentTemplate contiene el label que será modificado en el evento Tick del TimerControl1.


 


Ahora vamos a ver el código HTML que se genera al ejecutar la página:


 








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Transitional//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd»>

<html xmlns=»http://www.w3.org/1999/xhtml»>
<head id=»Head1″>
<title>Ejemplo de Atlas </title>
<style type=»text/css»>
.atlas__delta { font-family:Lucida Console; }
</style>
</head>
<body>
<form name=»form1″ method=»post» action=»Default.aspx» id=»form1″>
<div>
<input type=»hidden» name=»__EVENTTARGET» id=»__EVENTTARGET» value=»» />
<input type=»hidden» name=»__EVENTARGUMENT» id=»__EVENTARGUMENT» value=»» />
<input type=»hidden» name=»__VIEWSTATE» id=»__VIEWSTATE» value=»/wEPDwUKLTk0MDE4NzkyOWRk9EIOzqMN99vC4R+EqZ/Z/mUuyzc=» />
</div>
<script type=»text/javascript»>
<!–
var theForm = document.forms[‘form1’];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
// –>
</script>

</script src=»/AtlasJulio/WebResource.axd?d=_PQ3CYIRUazJB7M6SiIjSsYYjP76qKiR4TS1JTMp7m94q5o4IXP-fdF-NN6itFcADBLWhsNeag0rmZqQpUTFRiQiz894ql0Srt0Xs2KYgV01&amp;t=632899634700000000″
type=»text/javascript»>

</script src=»atlasglob.axd» type=»text/javascript»>

<table id=»__ErrorContainer» style=»display: none; margin: auto; text-align: center;»>
<tbody>
<tr>
<td>
<div style=»border-right: #000000 1px solid; padding-right: 12px; border-top: #000000 1px solid;
padding-left: 12px; padding-bottom: 12px; border-left: #000000 1px solid; width: 400px;
padding-top: 12px; border-bottom: #000000 1px solid; height: 140px; background-color: white;
text-align: left»
>
Ha ocurrido un error. <a id=»__ErrorContainer_okButton» href=»javascript:__doPostBack(‘__ErrorContainer$okButton’,»)»>
Aceptar</div>
</td>
</tr>
</tbody>
</table>
<div id=»UpdatePanel1″>
</span id=»Label1″>
</div>
<div>
<input type=»hidden» name=»__EVENTVALIDATION» id=»__EVENTVALIDATION» value=»/wEWAgLC49/9AgLQ4paJD3Bo5bbGWI5+cu56TzJXcuS9oH3J» />
</div>

<script type=»text/xml-script»>
<page xmlns:script=»http://schemas.microsoft.com/xml-script/2005″>
<components>
<pageRequestManager id=»_PageRequestManager» updatePanelIDs=»UpdatePanel1″ asyncPostbackControlIDs=»» scriptManagerID=»ScriptManager1″ form=»form1″ errorContainerID=»__ErrorContainer» />
<timer interval=»1000″ enabled=»true»>
<tick>
<postBack target=»TimerControl1″ eventArgument=»» />
</tick>
</timer>
<control id=»__ErrorContainer» visibilityMode=»Collapse»>
<bindings>
<binding dataContext=»_PageRequestManager» dataPath=»inErrorMode» property=»visible» />
</bindings>
</control>
<button id=»__ErrorContainer_okButton»>
<click>
<invokeMethod target=»_PageRequestManager» method=»clearError» />
</click>
</button>
</components>
</script>

<script type=»text/javascript»>
</script>

</form>
</body>
</html>


 


Lo primero que vemos importante en este código son una serie de campos ocultos:


 








1
2
3
<input type=»hidden» name=»__EVENTTARGET» id=»__EVENTTARGET» value=»» />
<input type=»hidden» name=»__EVENTARGUMENT» id=»__EVENTARGUMENT» value=»» />
<input type=»hidden» name=»__VIEWSTATE» id=»__VIEWSTATE» value=»/wEPDwUKLTk0MDE4NzkyOWRk9EIOzqMN99vC4R+EqZ/Z/mUuyzc=» />


 


Son los campos ocultos de ASP.NET (EventTarget, EventArgument y el famoso ViewState), necesarios para que el sistema de eventos de ASP.NET funcione junto con un Script que hace los PostBacks y genera el ViewState para que la página pueda ser recuperada en el servidor:


 








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        <script type=»text/javascript»>
<!–
var theForm = document.forms[‘form1’];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
// –>
</script>
 


Lo siguiente que vemos ya es más interesante para el tema que tratamos ahora:


 








1
2
3
        </script src=»/AtlasJulio/WebResource.axd?d=_PQ3CYIRUazJB7M6SiIjSsYYjP76qKiR4TS1JTMp7m94q5o4IXP-fdF-NN6itFcADBLWhsNeag0rmZqQpUTFRiQiz894ql0Srt0Xs2KYgV01&amp;t=632899634700000000″
type=»text/javascript»>
</script src=»atlasglob.axd» type=»text/javascript»>
 


 


Esos Scripts importan el Framework de Atlas a nuestra página.


 


Si seguimos mirando nos encontramos con una tabla oculta:


 








1
2
3
4
5
6
7
8
9
10
11
12
13
14
        <table id=»__ErrorContainer» style=»display: none; margin: auto; text-align: center;»>
<tbody>
<tr>
<td>
<div style=»border-right: #000000 1px solid; padding-right: 12px; border-top: #000000 1px solid;
padding-left: 12px; padding-bottom: 12px; border-left: #000000 1px solid; width: 400px;
padding-top: 12px; border-bottom: #000000 1px solid; height: 140px; background-color: white;
text-align: left»
>
Ha ocurrido un error. <a id=»__ErrorContainer_okButton» href=»javascript:__doPostBack(‘__ErrorContainer$okButton’,»)»>
Aceptar</div>
</td>
</tr>
</tbody>
</table>
 


Se trata de la que se mostrará en caso de que haya un error en la actualización. Y más adelante una capa:


 








1
2
3
        <div id=»UpdatePanel1″>
</span id=»Label1″>
</div>
 


Es, como podéis observar, el UpdatePanel de nuestra página con su respectivo Label1 dentro.


 


Y ahora toca lo interesante:


 








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        <script type=»text/xml-script»>
<page xmlns:script=»http://schemas.microsoft.com/xml-script/2005″>
<components>
<pageRequestManager id=»_PageRequestManager» updatePanelIDs=»UpdatePanel1″ asyncPostbackControlIDs=»» scriptManagerID=»ScriptManager1″ form=»form1″ errorContainerID=»__ErrorContainer» />
<timer interval=»1000″ enabled=»true»>
<tick>
<postBack target=»TimerControl1″ eventArgument=»» />
</tick>
</timer>
<control id=»__ErrorContainer» visibilityMode=»Collapse»>
<bindings>
<binding dataContext=»_PageRequestManager» dataPath=»inErrorMode» property=»visible» />
</bindings>
</control>
<button id=»__ErrorContainer_okButton»>
<click>
<invokeMethod target=»_PageRequestManager» method=»clearError» />
</click>
</button>
</components>
</script>


 


Es un Script en formato XML. SI lo observamos detenidamente veremos como funciona:


 







1
<page xmlns:script=»http://schemas.microsoft.com/xml-script/2005″>


 


Se importa el esquema del XML y acto seguido se abre la etiqueta components. El primer componente que veremos es el pageRequestManager:


 







1
    <pageRequestManager id=»_PageRequestManager» updatePanelIDs=»UpdatePanel1″ asyncPostbackControlIDs=»» scriptManagerID=»ScriptManager1″ form=»form1″ errorContainerID=»__ErrorContainer» />


 


Como podemos observer contiene que controles usarán las respuestas asincrónicas, como se llama el scriptManager, el nombre del form y el nombre de la tabla que contiene el mensaje en caso de error.


 


El siguiente es el Timer:


 








1
2
3
4
5
    <timer interval=»1000″ enabled=»true»>
<tick>
<postBack target=»TimerControl1″ eventArgument=»» />
</tick>
</timer>
 


Incluye el intervalo de actualización, y su nombre. Vemos luego otros dos nuevos controles:


 








1
2
3
4
5
6
7
8
9
10
    <control id=»__ErrorContainer» visibilityMode=»Collapse»>
<bindings>
<binding dataContext=»_PageRequestManager» dataPath=»inErrorMode» property=»visible» />
</bindings>
</control>
<button id=»__ErrorContainer_okButton»>
<click>
<invokeMethod target=»_PageRequestManager» method=»clearError» />
</click>
</button>


 


El __ErrorContainer es el que se mostrará en caso de error y el __ErrorContainer_okButton es el que se usará para cerrar el mensaje de error.


 


Por último y como anécdota. El código HTML generado en ejecución (el mostrado en este ejemplo) lo he guardado en un archivo llamado Default.aspx.htm y al ejecutarlo funciona perfectamente, cada un segundo se actualiza la hora de la página:


 



Que hay debajo de Atlas - Figura3


 


He conseguido el JavaScript del Framework de Atlas y os lo dejo disponible para descargar. Lo hubiese incluido en el Post, pero ocupa 237 páginas de Word… y casi como que no… ¿no creéis?


 


Descargas:



Nota: Para la edición de este artículo me baso única y exclusivamente en la lectura y posterior interpretación del código ASP.NET y HTML, basándome en mis conocimientos de HTML, JavaScript, ASP.NET, la metodología AJAX y Atlas. 

2 thoughts on “¿Qué hay debajo de Atlas?

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *