Marc Rubiño

ASP.NET, C#, AJAX.NET, JavaScript, etc.

April 2010 - Artículos

Charla CatDotNet - Novedades ASP.NET 4.0 VS 2010

sv2010 Todo aquel que esté cerca de Igualada este Jueves 29-04-2010 y le interese ver las novedades que nos aporta ASP.NET con el Framework 4.0 y el nuevo Visual Studio. Está invitado a pasarse por el grupo de usuarios CatDotNet y  pasar un buen rato. La excusa es esta charla pero el resultado seguro que será el buen rato que pasaremos entre todos.

Pues nos vemos este jueves a las 19h:

Sala Ig-Nova Tecnospai. Av. Barcelona núm. 105 (Igualada)

http://catdotnet.blogspot.com/2010/04/marc-rubino-igualada-aspnet.html

Saludos.

Posted: 27/4/2010 9:39 por Marc Rubiño | con 4 comment(s)
Archivado en: ,
/*El Mundo de los desarrolladores es Infinito…*/

image NO me lo puedo creer !!! después de responder a las preguntas en las vegas no salgo en el video !!! Pero creo que es normal ;-) me pillaron comiendo y con la boca llena no se responde.

Ahora en serio!!! Gana varios premios subiendo tu propio video respondiendo a unas simples preguntas.

 

image

Participaaaa !!! http://www.delinfinitoalmasalla.com/

FREE eBook: .NET Performance Testing and Optimization

Pues eso, tenéis disponible para descargar esta completa guía para generar pruebas de rendimiento y optimización de vuestras aplicaciones en .NET de Paul Glavich y Chris Farrell.

dotnet_performance_testing_and_optimization_ebook_cover_160h

  • Chapter 01: Introduction - The What and the Why
  • Chapter 02: Understanding Performance Targets
  • Chapter 03: Performance and Load Test Metrics
  • Chapter 04: Implementing your Test Rig
  • Chapter 05: Creating Performance Tests
  • Chapter 06: Next Steps - Profiling
  • Chapter 07: Performance Profiling
  • Chapter 08: Memory Profiling
  • Chapter 09: The Performance Testing Process
  • Chapter 10: Common Areas for Performance Improvement
  • Chapter 11: Load Balancing
  • Chapter 12: Internet Information Server (IIS)
  • Chapter 13: HTTP Optimization

     

    http://www.red-gate.com/products/ants_performance_profiler/want_to_be_dotnet_perf_testing_expert_ebook.htm

     

     

  • Posted: 13/4/2010 9:39 por Marc Rubiño | con 1 comment(s)
    Archivado en:
    Cargar Controles de Usuario dinámicamente ASP.NET AJAX

    En respuesta a la consulta de Julitogtu generada en los foros de MSDN, he generado un ejemplo práctico de su consulta. Ya que le aconsejé la utilización de controles de usuarios generados dinámicamente en detrimento de los famosos iframes.

    Pero esta generación se complica especialmente si quieres cargar estos controles con llamadas asíncronas, por el hecho de que estos controles se generan en el servidor.

    Lo primero que tenemos que hacer es tener los controles de usuario bien organizados para poderlos utilizar desde el cliente con llamadas a métodos de Página o servicios web, de esta manera evitaremos todo el tráfico que genera los updatePanels.

    image

    Yo he generado tres controles de usuarios distintos para probar diferentes posibilidades que nos podemos encontrar en la vida real.

    • Un formulario: Encontraremos los típicos controles asp.net para introducir los datos de un formulario.
    • Login: Dentro de este control tendremos otro ASP.NET para la creación de usuarios registrados.
    • Grid: Control de usuarios donde mostraremos los datos de una base de datos con un GridView.

    Después en la página principal de la aplicación tendremos un TreeView para seleccionar los controles a cargar y un div donde se mostrara la información.

    Cargaremos la lista manualmente y le indicaremos a los nodos que en cuanto se selecciones ejecuten el método de página que devolverá el control de usuario en formato texto, para esto solo le pasaremos el nombre de la función y el identificador del control que queremos cargar en el enlace.

    private void CargarDatos()
    
    {
    
      Dictionary<string,string> controles = 
    
                      new Dictionary<string,string>();
    
      controles.Add("FormControl", "Datos de contacto");
    
      controles.Add("GridControl", "Lista de Productos");
    
      controles.Add("LoginControl", "Iniciar sesión");
    
    
    
      foreach (KeyValuePair<string, string> value in controles)
    
      {
    
        TreeNode node = new TreeNode();
    
        node.Text = value.Value;
    
        node.NavigateUrl = "BLOCKED SCRIPTPageMethods.CargarControl('"
    
           + value.Key +"', CargarControlOK, CargarControlKO);";
    
        TreeView1.Nodes.Add(node);
    
       }
    
    }

    Código de servidor:

    La página contará de un Método de Página que se encargara de cargar el control de Usuario y transformara el control en el resultado HTML que es el que se devolverá al cliente para que se añada al div y muestre el control en el navegador.

    [WebMethod]
    
    public static string CargarControl(string tipoControl)
    
    {
    
       StringWriter stringWriter = new StringWriter();
    
       Page page = new Page();
    
       System.Web.UI.HtmlControls.HtmlForm form = 
    
         new System.Web.UI.HtmlControls.HtmlForm();
    
       form.ID = "__t";
    
       page.Controls.Add(form);
    
    
    
       switch (tipoControl)
    
       {
    
         case "FormControl":
    
         {
    
           UserControls_Form cForm = 
    
            (UserControls_Form)page.LoadControl("~/UserControls/FormControl.ascx");
    
           form.Controls.Add(cForm);
    
           HttpContext.Current.Server.Execute(page, stringWriter, false);
    
           break;
    
         }
    
         case "GridControl":
    
         {
    
           UserControls_Grid cGrid = 
    
            (UserControls_Grid)page.LoadControl("~/UserControls/GridControl.ascx");
    
           cGrid.Inicializar("Condiments");
    
           form.Controls.Add(cGrid);
    
           HttpContext.Current.Server.Execute(page, stringWriter, false);
    
           break;
    
         }
    
         case "LoginControl":
    
         {
    
           UserControls_Login cLog = 
    
            (UserControls_Login)page.LoadControl("~/UserControls/LoginControl.ascx");
    
           form.Controls.Add(cLog);
    
           HttpContext.Current.Server.Execute(page, stringWriter, false);
    
           break;
    
        }
    
      }
    
      //Limpiamos el formulario ASP
    
      string html=(stringWriter != null)?stringWriter.ToString():"<h2>Sin Datos</h2>";
    
      html = html.Substring(html.IndexOf("<div>"));
    
      html = html.Substring(0, html.IndexOf("</form>"));
    
    
    
      return html;
    
    }

    Al utilizar Métodos de Página o Servicios web no existe el estado y tenemos que generar una página ASP.NET y ejecutarla para que se generen los controles y poder mostrar su resultado HTML. Esta idea esta extraída del fenomenal artículo de Scott Guthrie:  Ajax views. Pero uno de los inconvenientes que nos encontramos con esta técnica es que obtenemos el formulario completo, por ese motivo hay que limpiar el HTML y eliminar el rastro del formulario.

    Otra cosa que tenemos que tener en cuenta es que podemos controlar en que momento tenemos que cargar los datos en el control, yo en este caso he generado una función que se encarga de inicializar y cargar los datos filtrados directamente con un objeto SQLDataSource.

    public void Inicializar(string Categoria)
    
    {
    
       SqlDataSource1.SelectParameters.Add("CategoryName", Categoria);
    
       SqlDataSource1.SelectCommand = 
    
        @"SELECT [ProductID], [ProductName], [CategoryName] 
    ";
    
          FROM [Alphabetical list of products] 
    
             WHERE ([CategoryName] = @CategoryName)
       GridView1.DataSourceID = "SqlDataSource1";
    
       GridView1.DataBind();
    
    }

    Código Cliente:

    Tendremos dos funciones, una para recoger el resultado y cargar el div “utilizando JQuery” y el otro mostraremos  un mensaje en el caso que ocurra un error.

    function CargarControlOK( resultado ){
    
        if ($(".divBase").length)
    
           $(".divBase")[0].innerHTML = resultado;        
    
    
    
    }
    
    function CargarControlKO(resultado){
    
    
    
        alert("Error al cargar el menú: " + resultado._message)
    
    }

    Resultado:

    El resultado obtenido en esta práctica, es que al seleccionar un nodo del treeView se genera una llamada asíncrona que no carga todo la página y carga en un div el control de usuario que se especifica en la llamada, de esta manera podemos reutilizar toda la funcionalidad que nos aportan estos controles.

    Podéis pasar el código de una página aspx de una forma muy sencilla a un control de usuario sin tener que repicar todo el código Cómo: Convertir páginas de formularios Web Forms en controles de usuario ASP.NET

    image

     

    image

     

    image

     

    Espero que esta información sea de utilidad.

    Ejemplo:  http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/mrubino.Ejemplos/UserControlsAjax.zip 

    Cancelar peticiones ASP.NET AJAX

    ASP_NET-AJAX Para plantear la cancelación de una llamada asíncrona realizada con ASP.NET AJAX primero tenemos que tener en cuenta como hemos realizado esta petición, para realizar esta acción podemos elegir entre dos opciones diferenciadas.

    1. El control UpdatePanel que encapsula las peticiones web de forma asíncrona.
    2. Las llamadas a Métodos de Páginas o Servicios web desde el cliente.

    1. UpdatePanel

    Si hemos elegido la primera opción, cualquier control que realice una petición al servidor será controlada por el ScriptManager y podremos utilizar este mismo control para cancelar la tarea del cliente.

    Para poder habilitar la cancelación al cliente usaré una barra de progreso la cual informará al usuario que se esta realizando una tarea y además tendrá un botón para poder cancelar este proceso.

    ProgressCCentrar UpdateProgress en un UpdatePanel ( JQuery )

    Lo único que necesitamos es que el botón de la barra de progreso llame a una función javascript, que será la encargada de anular la petición.

    function Cancelarproceso() {
    
    
    
      var proceso = Sys.WebForms.PageRequestManager.getInstance();
    
      if (proceso.get_isInAsyncPostBack()) {
    
          proceso.abortPostBack();
    
      }
    
      if ($('input[type=submit]').length)
    
          $('input[type=submit]').attr('disabled', false);
    
    
    
      $("#progress").hide();
    
      //Para no enviar el evento al servidor.
    
      return false;
    
    }

    Este código recupera la instancia del PageRequestManager y si es un postBack asíncrono llama a la función abortPostBack().

    2. Métodos de Página

    Teniendo en cuenta las penalizaciones al utilizar los UpdatePanels en el rendimiento y que solo podemos tener una llamada asíncrona a la vez, podemos optar por utilizar los métodos de página para realizar múltiples llamadas asíncronas y de una manera mas ligera.

    En este ejemplo utilizo una lista para lanzar multiples llamadas al servidor y mostrar una animación para avisar al usuario que el proceso esta en marcha, de la misma manera damos la opción de anular cada llamada con un botón enlazado a cada proceso.

    ProgressMultiC

     

    ¿Como funciona este el control?

    1. El botón actualizar recorre la lista y lanza todos los procesos que estén con el check seleccionado.
    2. Creo un Array en Javascript para guardar la instancia del método de página utilizado y poderlo identificar cada una de las llamadas.
      var p = new Array();
      
      
      
      function lanzarprocesoAsinc(div, n) {
      
          var par = div + "|" + $("#" + div).attr("cr") + 
      
              "|" + $("#" + div).attr("tran");
      
          p[n] = PageMethods._staticInstance.LanzarprocesoCRI(par, 
      
              lanzarprocesoCRI_OK, lanzarprocesoCRI_KO, div);
      
      }
      
      
      
      
      
    3. Cuando se presiona el botón de anulación se invoca una función javaScript que localiza la instancia de la petición asíncrona y anula el proceso.  Recuperamos el elemento de ejecución de la instancia y si no está marcada como abortada, la marca. Finalmente oculta la barra de progreso del elemento de la lista.
    function AnularProcesoAsinc(n, div) {
    
        var executor = p[n].get_executor();
    
        if (executor.get_started()) {
    
            if (!executor._aborted) {
    
                executor.abort();
    
                $("#" + div).show("slow");
    
                $("#"+ div+ "_W").hide("slow");
    
            }
    
        }
    
    }

    Muy Importante !!!

    Cuando habilitas la anulación de un proceso asíncrono tienes que tener muy claro que solo se anula la devolución del cliente. Que solo se cierra el socket de cliente del cual se reciben las respuestas. No hay repercusión en el código que se ejecuta en el servidor.

    Para hacer que todo el proceso finalice, tienes que tener todo tu modelo previamente estructurado y pensar cual de estos procesos se pueden anular y cuales no. Si quieres profundizar en este sentido tienes el artículo de Dino Esposito donde explica estas situaciones mas detalladamente Cutting Edge:Cancelación de las tareas de servidor con AJAX de ASP.NET.