Tip para detectar bloqueador de popup.

Los bloqueadores de popups nos invaden ultimamente, las personas tienen de 1 a más de 5 bloqueadores a veces y eso muchas veces nos genera problemas al intentar mostrar los popups.

Lo ideal sería detectar si se tiene activado algun bloqueador para mostrar alguna alerta a nuestros usuarios respecto a ello y que no se confundan respecto a la no aparición de la ventanita, aca va una función javascript sencilla que nos podría servir para ello:

function DetectarBloqueador()
{
    var blnBloqueado;
    var ventana = window.open('','','width=1,height=1,left=0,top=0,scrollbars=no');
    if(ventana)
        blnBloqueado = false
    else
        blnBloqueado = true
    ventana.close()
   
    return blnBloqueado;
}

Es sencilla de entender y nos devuelve un valor boleano indicando si existe algún bloqueador de popups activado o no.

Saludos cordiales,

Ivan Mostacero.

Problemas comunes con ASP .NET Ajax Beta 1

Wow que semana, tuve que ir lidiando uno a uno con un conjunto de problemas de Ajax en su versión Beta 1 y 2. El problema principal y más complicado que se tuvo fue debido a un bug de Internet Explorer v6 con Service Pack 1 para archivos que son enviados utilizando compresión.

El dilema es el siguiente, ASP .NET Ajax Beta 1 y 2, utilizan un módulo de compresión para enviar los archivos javascript al cliente, si bien es cierto esta funcionalidad reduce a una cuarta parte el tamaño de los archivos, el equipo de asp.net no contó con un pequeño detalle, que con el Service Pack 1 de Internet Explorer habian deshabilitado esta funcionalidad, osea, en otras palabras te van a saltar mil y un errores cuando se corra sobre un internet explorer 6 con service pack 1 sino tienes instalado el Parche KB912812, osea todo cargaría bien en un Firefox, en un Netscape excepto en los IE que no tengan este parche =(, y simplemente no funcionaría casi nada que tengas implementado con ASP .NET Ajax.

Los errores que se obtienen son los siguientes:
* 'Sys' is undefined.
* Expected '}'
* 'Type' is undefined

Bueno la solución es instalar en los internet explorer que boten esos errores el parche requerido: Cumulative Update for Internet Explorer 6 SP1 (KB912812)

Lo pueden descargar desde la siguiente URL:
http://www.microsoft.com/downloads/details.aspx?familyid=033C41E1-2B36-4696-987A-099FC57E0129&displaylang=en

Elijan el lenguaje de su explorer y listo, en si esto no es una solución que se le puede dar a un cliente desde luego, esperemos que la siguiente versión ya todo esto se haya mejorado, no hay duda de esto por la rápida reacción que está adoptando Microsoft y en especial el equipo de ASP .NET, un tip al respecto en caso tengan este problema sin solución aparente, dentro del archivo Web.Config tenemos la siguiente entrada:

<add name="WebResourceCompression" type="Microsoft.Web.Handlers.WebResourceCompressionModule, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

Retírenla temporalmente hasta que este problema haya sido cubierto, este handler maneja la parte de la compresion en Ajax.

Espero sea de utilidad,

Ivan Mostacero.

Microsoft Visual Studio 2005 IDE Enhancements

Listo para descargar, tenemos disponibles un conjunto de extensiones para visual studio 2005 que nos ayudarán a ser mas productivos en el desarrollo, si bien ciertas mejoras la teniamos disponibles antes pero con la necesidad de tener el SDK instalado, ahora ya no requiere el SDK 🙂

En este pack tenemos:

* Source code outliner.
* Visual C++ Code Snippets.
* Indexed find.
* Super Diff utility.
* Event Toaster Utility.

La descarga la pueden ealizar aca mismo: http://www.microsoft.com/downloads/details.aspx?FamilyID=cd7c6e48-e41b-48e3-881e-a0e6e97f9534&DisplayLang=en

Espero sean de utilidad, Saludos 🙂

Ivan Mostacero

Cambios en el Update Panel en la Version Beta de ASP.NET Ajax

Aca van algunos de los cambios que se han implementado:

1. La propiedad "Mode" fue cambiada por "UpdateMode", los valores que ésta pueda tomar si son los mismos.
2. La sección ControlEventTrigger cambió a AsyncPostBackTrigger, y también se quitó la opción de disparar triggers cuando cambie el valor de un determinado control.
3. Se agregó la sección PostBackTrigger dentro de triggers, esto con la intensión de que aunque un control esté dentro de un UpdatePanel tambíen debería existir la opción de realizar un Postback común y corriente(osea como si no estuviera en un UpdatePanel).
4. Se le adicionó una nueva propiedad muy interesante llamada "ChildrenAsTriggers", que va a sernos muy útil para el caso de manejar la propiedad UpdateMode igual a "Conditional", si ponemos esta propiedad a False implica que si un control dentro de este UpdatePanel realiza un partial Postback se van a refrescar los "otros" UpdatePanel que sean disparados por este control, mas NO el mismo UpdatePanel que lo contiene, interesante cierto 🙂
5. Se ha mejorado muchísimo la integración con el Objeto PageRequestManager, permitiendonos ahora tener metodos del lado del cliente para muchos eventos como beginRequest, end Request, entre otros.
6. Mejor integración del Update Panel tanto con controles de validación y con controles Wizard debido a varios bug reportados (Que bueno que al fin se haya mejorado esto, sufri mucho en la versión anterior respecto a los controles validators dentro de un control wizard).
7. La posibilidad de poder asociar varios UpdateProgress dentro de la página al mismo UpdatePanel, debido a que se le agregó a los UpdateProgress una propiedad llamada "AssociatedUpdatePanelID" donde se define sobre que control UpdatePanel va a trabajar 🙂

Estas son algunas de las mejoras que e ido descubriendo respecto a este control 🙂 es bueno saber que día a día se mejora este framework que será de mucha utilidad 🙂

Ivan Mostacero.

ASP.NET Ajax: ScriptManager y OnAsyncPostBackError

Debido a que dentro del ScriptManager ya no tenemos un ErrorTemplate que nos permita definir errores que se dan dentro de un partial postback, debemos realizar una implementación parecida, combinando eventos que tenemos dentro del ScriptManager y el Control ModalPopupExtender, como realizariamos esto?

Primero: Agregamos el Control ScriptManager en nuestra página tal como sigue:

<asp:ScriptManager ID="smMaster" runat="server" EnablePartialRendering="True" OnAsyncPostBackError="smMaster_AsyncPostBackError"></asp:ScriptManager>

asp:ScriptManager ID="smMaster" runat="server" EnablePartialRendering="True" OnAsyncPostBackError="smMaster_AsyncPostBackError"></asp:ScriptManager>

Segundo: Definimos en nuestro Code Behind un método que maneje el evento OnAsyncPostBackError de la siguiente manera:

protected void smMaster_AsyncPostBackError(object sender, Microsoft.Web.UI.AsyncPostBackErrorEventArgs e)
{
Microsoft.Web.UI.ScriptManager.GetCurrent(this.Page).AsyncPostBackErrorMessage = ErrorManager.ObtenerMensajeSistema();
}

lo que hemos definido aca es asignar a la propiedad AsynPostBackErrorMessage un mensaje del sistema personalizado, si uds quieren mostrar el verdadero error que esta causando la excepción lo asignarian  a "e.Exception.Message".

Tercero: Definimos un control ModalPopupExtender que contenga el Panel a mostrar con el mensaje de error(Esto hara que el mensaje salga centrado en la pantalla y de acuerdo a los estilos definidos bloquear el fondo de la misma).

<asp:Button ID="btnCambiarDatos" runat="server" Style="display: none;" />
<asp:ModalPopupExtender ID="ModalPopupExtender" runat="server" BehaviorID="mppDatos" TargetControlID="btnCambiarDatos" PopupControlID="pnlPopup" BackgroundCssClass="modalBackground1" OkControlID="btnAceptar" DropShadow="false" CancelControlID="imgCerrar">
</asp:ModalPopupExtender> 

Ojo, Uds deben definir el PopupControlID que seria un panel con el mensaje a mostrar, pornerle algun label para mostrar el mensaje.

Cuarto: Ahora si debemos manejar el resultado del partial postback, esto lo hacemos a través del Objeto PageRequestManager encargado de manejar los partial postback de los diferentes UpdatePanel que se tuviera, aprovechando uno de sus eventos: "add_endRequest", este evento justamente se da luego de haberse dado el partial postback y nos trae cierta información para trabajar, lo hacemos de la siguiente manera:

<script type="text/javascript" language="javascript">
var messageElem = '<%= lblDatos.ClientID %>';
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

function EndRequestHandler(sender, args)
{
if (args.get_error() != undefined && args.get_error().httpStatusCode == '500')
{
var errorMessage = args.get_error().message
args.set_errorHandled(true);
$get(messageElem).innerHTML = errorMessage;
$find("mppDatos").show();
}
}

script type="text/javascript" language="javascript">
var messageElem = '<%= lblDatos.ClientID %>';
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

function EndRequestHandler(sender, args)
{
if (args.get_error() != undefined && args.get_error().httpStatusCode == '500')
{
var errorMessage = args.get_error().message
args.set_errorHandled(true);
$get(messageElem).innerHTML = errorMessage;
$find("mppDatos").show();
}
}

 

</script>

Pd: Si les sale un error respecto a que Sys.WebForms no está definido, es porque la propiedad EnablePartialRendering del ScriptManager está en false, solo borrándola ya que es por defecto en true, problema solucionado, esto es muy bueno ya que ahora solo se envía al cliente el javascript necesario para trabajar :).

Si analizamos el Snippet anterior se tiene que analizamos el mensaje de error y si existe lo manejamos nosotros mismos, ponemos el mensaje que nos devuelve el servidor en el label antes definido dentro de el popup que mostraremos y luego de ello ya mostramos nuestro Popup 🙂 utilizando el método show(), ojo el Id que usamos como parámetro del "find" viene a ser la propiedad BehaviorID que viene con el control ModalPopupExtender.

Ya uds. pueden personalizarlo mucho mas, como por ejemplo agregarle un DragPanelExtender para poder arrastrar la ventana en la pantalla o combinar con el framework de animaciones de ASP.NET Ajax para darle un mejor acabado 🙂

Buen dia,

Ivan Mostacero.

ASP.NET Ajax Beta 1: Cambios de la version Atlas.

Hoy día iniciamos la migración de uno de nuestros aplicativos basados en Ajax, realmente bastante tedioso, se han dado cambios significativos para esta versión beta, es cierto que hay muchas mejoras pero el trabajo de migración se ha tornado medio pesado, aca van algunas de mis apreciaciones:

PageMethods: Antes hacer llamadas a métodos marcados como [WebMethod] dentro de un formulario web, era muy simple, yo habia utilizado esto para hacer un render de ciertos controles de usuarios de los cuales obtenia su codigo HTML que era devuelto al cliente para su renderización (hacia unas 4 llamadas en paralelo lo cual mejoraba muchisimo la performance de carga además de solo renderizar lo necesario). Ahora me encontre con varios problemillas con esta utilidad, me parece que hay varios bugs involucrados tal como lo menciona uno de los miembros del equipo de ASP.NET aca en un post:

http://blogs.msdn.com/sburke/archive/2006/10/21/hint-components-that-use-web-services-with-asp-net-ajax-v1-0-beta.aspx

Asi que frente a esto opté por la posibilidad de realizar este trabajo a través de un servicio Web.

La opción de usar servicios Web ha sido mejorado muchísimo, si notamos el proxy que se generaba anteriormente a lo que se genera en esta versión notaremos que se ha incluído el patron prototype para su implementación. eso es muy interesante para opciones de depuración que podrían venir en Orcas, ahora los servicios web cambiaron tambien en algo, debemos agregarle en la cabecera lo siguiente:

[Microsoft.Web.Script.Services.ScriptService()]
public class TiempoService : System.Web.Services.WebService {

Ahora si hablamos del control principal de ASP.NET Ajax, el ScriptManager también a cambiado en muchos aspectos tal como he ido comprobando en este proceso de migración que venimos realizando:

* Por defecto la propiedad  "EnablePartialRendering" está en true, esta funcionalidad nos ayuda con el manejo del UpdatePanel 🙂 asi que si uds no trabajan con este control y en vez de ellos utilizan llamadas directas a un servicio web les recomiendo que le pongan el valor de false.
* Ya no existe el "ErrorTemplate", mas bien se ha reemplazado por: AsyncPostBackErrorMessage(esto me parece muy interesante aunque me hizo rabiar un poco al tener que borrar mis errorTemplates 🙁 ).

Ahora si ya vamos al uso de los controles partes del AjaxControlToolkit veremos tambien cambios:

Por ejemplo:

Antes:
<AtlasToolkit:ModalPopupExtender ID="ModalPopupExtender1" runat="server">
<AtlasToolkit:ModalPopupProperties ID="mpp" TargetControlID="hypModal" PopupControlID="pnlPopup" BackgroundCssClass="fondo" />
</AtlasToolkit:ModalPopupExtender>

Despues:
<ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender1" runat="server" BehaviorID="mpp"
PopupControlID="pnlPopup" TargetControlID="hypModal" BackgroundCssClass="fondo">
</ajaxToolkit:ModalPopupExtender>

Primeros cambios interesantes, el ID que se definia dentro de el ModalPopupProperties ahora a sido reemplazado por el BehaviorID asi que no se preocupen si han realizado programación a través de javascript de estos objetos aún estan disponibles solo que se han reordenado las propiedades y renombrado algunas :).

Por ejemplo yo antes para mostrar el popup hacia lo siguiente(Usando el ID):
$object("mpp")._show();
Ahora debo hacer:
$find("mpp").show();

(Upps, notarán que también ha cambiado el nombre de algunos métodos 🙁 más trabajo de migra)

y para terminar este post, algo respecto a la clase PageRequestManager (encargada de manejar las llamadas asincronas, muy utilizada para manejar eventos al iniciar y terminar un partial postback) tambien ha tenido algunos cambios.

Por ejemplo antes para mostrar el popup al iniciar una llamada utilizando el updatePanel usaba lo siguiente:

function pageLoad()
{
var prm = $object("_PageRequestManager");
prm.propertyChanged.add(onRequestChange);
}

function onRequestChange(sender, eventArgs)
{
if (eventArgs.get_propertyName() == "inPostBack")
{
if ($object("_PageRequestManager").get_inPostBack())
{
$object("mppModal")._show();
}
else
{
$object("mppModal")._hide();
}
}
}

Ahora ha cambiado a lo siguiente:

function pageLoad()
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler)
}

function BeginRequestHandler(sender, args)
{
$find("mpp").show();
}
function EndRequestHandler(sender, args)
{
$find("mpp").hide();
}

Wow muchos cambios pera a la vez muy interesante, muy emocionado hasta ahora como con juguetito nuevo 🙂

Iré contandoles más novedades de ASP.NET Ajax Beta en el transcurso de la semana,

Un saludo desde perú,

Ivan Mostacero

P.D. El tamaño de las librerías js ha disminuido bastante, y solo se envía lo necesario al cliente, algo muy esperado que lo comprobe claro usando Fiddler 🙂 en mi caso solo está enviando un promedio de 10k en librerias js al cliente, muchiiiisimoo mejor que lo que se enviaba en la versión anterior.

ASP.NET Ajax Beta 1 a sido liberado!

Asi como lo escuchan, se acaba de liberar el primer beta oficial de Microsoft ASP.NET Ajax v1.0 que incluye:
* ASP.NET Ajax v1.0 Core
* ASP.NET Ajax "Value-Add"
* ASP.NET Ajax Control Toolkit

Se han realizado algunos cambios para este beta, entre ellos:

* Optimizaciones en Performance y tamaño de descarga (Muy esperado por cierto). Para lograr esto se ha dividido los archivos principales javascript en muchos mas pequeños que se iran descargando de acuerdo a las necesidades.
* Soporte para el browser Safari(Justo a tiempo para los proyectos que venimos realizando 🙂 )
* Mejor soporte de depuracion.
* Muuuchas mejoras al control UpdatePanel (Una de las estrellas de atlas).
* Muchas mejoras mas a las librerias javascript.
* Compatibilidad con otras librerias Ajax.

Bueno algo que no me gusta es que para cambiar a esta beta debemos cambiar varias cosas a lo que ya se tiene, como el cambio del prefijo <atlas: a <asp: y manejo de triggers en los update panel (Muy malo 🙁 ), pero para ello contamos con una guia de migracion:

http://ajax.asp.net/files/Migration%20Guide.doc

Documentación adicional:
http://go.microsoft.com/?linkid=5637948

Más información:
http://weblogs.asp.net/scottgu/archive/2006/10/20/ASP.NET-AJAX-Beta-1-Released.aspx

Iré contandoles poco a poco sobre estos nuevos cambios 🙂

Saludos,

Ivan Mostacero.

ASP.NET Ajax: Utilizando el control ModalPopupExtender como una ventana Splash.

Hola amigos, estuve navegando por internet, y revisando uno de los nuevos servicios Live de Microsoft me encontre con una funcionalidad muy interesante en el portal de compras: http://shopping.live.com, referente al splash de espera que ahi se muestra cuando se quiere ver el detalle de alguna de las categorias de la izquierda:

 

 

 

 

 

 

 

 

 

 

 

 

La funcionalidad es muy simple, al momento de hacer la peticion hacia el servidor se carga esta ventanita de splash bloqueando la pantalla evitando asi otras peticiones.

Ahora vamos a implementar esta funcionalidad en ASP.NET Ajax, si bien es cierto en el ASP.NET Control Tookit tenemos un control denominado UpdateProgress, este control nos permite mostrar un template de espera al momento de hacer una peticion hacia el servidor usando algun UpdatePanel, en si podriamos adaptarlo para esta necesidad, pero se tienen varias restricciones al respecto, en mi caso, centre mas mi atencion en el Control ModalPopupExtender ya que este me permitiria realizar lo siguiente de manera nativa:

1. Bloquear toda la pantalla al momento de mostrar el popup (En este caso yo me encargaria de mostrar el popup tanto al momento de hacer Web Request a un servicio Web como cuando utilice algun UpdatePanel para mostrar Informacion)

Muy bien manos a la Obra.

Primero, el control ModalPopupExtender tiene la facilidad de convertir cualquier Panel en una ventana Modal bloqueando todos los demas controles de la pagina, esto se logra definiendo que control se encargara de disparar el evento para poder mostrarlo, en nuestro caso no requerimos que sea un control el encargado de mostrar el splash , sino que sea lanzado de manera personalizada. Es muy simple lograr este comportamiento, este control tiene dos metodos que nos van a ayudar a lograr este cometido:

_show() y _hide()

Estos metodos que se autoexplican en su nombre, nos ayudaran a mostrar y ocultar la ventana modal en el momento que nosotros desearamos, entonces podriamos hacer lo siguiente:

Definimos el objeto Modal poniendo un ID a la misma de la siguiente manera:

<cc1:ModalPopupExtender ID="ModalPopupExtender1" runat="server">
<cc1:ModalPopupProperties ID="mpp" PopupControlID="pnlPopup" TargetControlID="hypModal"
BackgroundCssClass="fondo" />
</cc1:ModalPopupExtender>

 

Luego de ello, en la funcion donde haremos la llamada al servicio web invocaremos al metodo _show del mismo, de la siguiente manera:

function onClick()
{
TiempoService.getTime(document.getElementById("txtNombre").value, onCallback, onTimeout, onError);
$object("mpp")._show();
return false;
}

muy bien eso hara que se muestre la ventana modal al momento de hacer la peticion hacia el servidor, todo perfecto hasta aca 🙂 pero, la idea es que al haber una respuesta por parte del Servidor, se oculte este control popup, esta rutina la realizariamos en las siguientes funciones javascript: onCallback, onTimeout, onError, por ejemplo:

function onCallback(result)
{
document.getElementById("spResultado").innerHTML = result;
$object("mpp")._hide();
}

Hasta ahora perfecto, ya tenemos funcionando nuestro splash tal y como la queriamos 😉 pero todo trabaja de la mejor manera siempre y cuando se hagan peticiones a servicios web como mostramos anteriormente, pero que sucede si tambien dentro de nuestra pagina tenemos controles UpdatePanel que hacen partial-postback hacia el servidor??? pues simplemente no se dispararia nuestra modal debido a que no sabemos en que momento se hace el callback por lo tanto no sabemos donde hacer la llamada, pero no hay porque apurarse 🙂 tambien existe solucion para ello, para ellos agregaremos un par de cositas adicionales:

function pageLoad()
{
$object("_PageRequestManager").propertyChanged.add(onPropertyChanges);
}

 

function onPropertyChanges(sender, e)
{
if (e.get_propertyName() == "inPostBack")
{
if ($object("_PageRequestManager").get_inPostBack())
{
$object("mpp")._show();
}
else
{
$object("mpp")._hide();
}
}
}

 

OK, que tenemos aca, primero tenemos la funcion pageLoad(), esta funcion se ejecuta siempre despues que se han cargado los scripts de Atlas en el cliente, lo que se ha hecho agregando esta linea  $object("_PageRequestManager").propertyChanged.add(onPropertyChanges); es definir una funcion (onPropertyChanges) a la cual se llamara luego de que se haya dado un cambio en alguna de las propiedades del Objeto "_PageRequestManager" que es el objeto encargado de administrar los controles UpdatePanel y que se genera de manera automatica.(Pueden uds observarlo dando boton secundario -> ver codigo fuente de la pagina que usa atlas)

Ahora dentro de esta funcion se pregunta sobre la propiedad "inPostBack" que es la propiedad que va a definir si se esta realizando un Partial-Postback por parte de alguno de los controles UpdatePanel que tengamos, por lo tanto si esta propiedad esta en True, es el momento adecuado de mostrar nuestra pantalla modal, en caso la respuesta sea False implica que ya concluyo el Partial-Postback por lo mismo ya es momento adecuado para ocultar nuestro control modal.

Con esto nuestra demo queda completa, aca les pongo el enlace con la demostracion del mismo, ha sido probado en los siguientes navegadores: IE 7, FF 1.5 y NC 8.1.

http://tinyurl.com/ukkqw

 Aqui una imagen del resultado final:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Como podemos observar ASP.NET ajax nos da un conjunto de funcionalidades que hace simple realizar trabajos complejos como en este caso 🙂 en realidad esta es una demostracion de lo mucho que podemos realizar combinando controles y utilizando lo que el Core de atlas nos da,

Un saludo cordial desde peru,

Ivan Mostacero.

ASP.NET Ajax y su integracion con Web Parts Framework.

Hola amigos, un nuevo fin de semana y estamos aca de vuelta para seguir con muchas novedades respecto a ASP .NET Ajax, esta vez veremos la integracion que se tiene con el Web Part Framework.

Muchos de Uds habran visto alguna demo o leido algun articulo respecto al Web Part Framework y de las muchisimas posibilidades que nos da para construir portales en donde es el usuario final el encargado de gestionar su informacion de acuerdo a su perfil, gustos y necesidades, de todos modos aca pongo un enlace usado para hacer la demo de este post, aca va la URL:

http://msdn.microsoft.com/msdnmag/issues/05/09/WebParts/

 

Les muestro a continuacion dos enlaces de la misma pagina, ambas basadas en el Web Part Framework, como les comente esta demo fue tomada de el enlace anteriormente mostrado, en el primer enlace uds veran en funcionamientos a los diferentes Web Parts que tenemos disponibles, en la parte superior uds pueden encontrar las diferentes vistas disponibles, vista de navegacion, edicion, diseño y de catalogo(en esta ultima uds encontraran web parts disponibles o webparts cerrados por el usuario), aca van los enlaces, ojo con el, logueo, en la parte inferior esta el usuario y pass con el cual se puede ingresar.

Link 01 : http://www.transportesjoselito.com/atlas/webparts/default.aspx

Link 02 : http://www.transportesjoselito.com/atlas/WebParts/DefaultAtlas.aspx

Update: Para poder ingresar no se olviden de ingresar como usuario bob y como password pass@word1

(El dominio es de un amigo que me ha permitido subir las paginas temporalmente)

La diferencia entre ambas es que a la segunda le aplicamos las extensiones de Ajax para web parts y agregando el control UpdatePanel y UpdateProgress correspondiente logramos una mejor experiencia con el usuario, es muy simple lograr esta funcionalidad, para lograrlo primero debemos agregar un mapeo de tags en el web.config dentro de la section Pages, en si lo siguiente:

<pages theme="Wingtip">
<tagMapping>
<add tagType="System.Web.UI.WebControls.WebParts.WebPartManager" mappedTagType="Microsoft.Web.UI.Controls.WebParts.WebPartManager"/>
<add tagType="System.Web.UI.WebControls.WebParts.WebPartZone" mappedTagType="Microsoft.Web.UI.Controls.WebParts.WebPartZone"/>
</tagMapping>
<controls>
<add namespace="Microsoft.Web.UI" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
<add namespace="Microsoft.Web.UI.Controls" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
</controls>
</pages>

 el siguiente paso es agregar un ScriptManager y un UpdatePanel dentro de la pagina basada en webparts que contenga a las webpartzones y listo 🙂

Un saludo muy grande,

Ivan Mostacero.

P.D: si bien es cierto que se obtiene una mejor experiencia para el usuario, no es la mejor performance que se podria obtener debido a que en cada callback se realiza un renderizacion casi completa de la pagina, espero sus opiniones 🙂