Archive for the ASP.NET Category

ASP.NET MVC y NHibernate (Partes 1 y 2)

Posted in Aplicaciones, ASP.NET, Tutorial on noviembre 3, 2009 by César Intriago

Tengo publicados dos artículos sobre cómo empezar a trabajar con NHibernate y ASP.NET MVC, puede leerlos desde el sitio de ForerunnerG34:

Espero les sirva de ayuda para las personas que recién están empezando con NHibernate"!

Bienvenido Forerunner-G34

Posted in ASP.NET, Noticias, WPF on octubre 30, 2009 by César Intriago

forerunenrG34

Mi nuevo blog sobre ASP.NET y WPF (and it’s Green):
[ http://forerunnerg34.wordpress.com ]

HTML Render de controles ASP.NET

Posted in ASP.NET, Microsoft, Tutorial on octubre 2, 2009 by César Intriago

 

Hace algún tiempo, en una compañía dedicada a consultaría Web en donde trabajaba surgió un requerimiento de “integrar” ASP.NET con un CMS que permite únicamente tener contenido estático HTML, CSS y JavaScript en tiempo de diseño.

El escenario era el siguiente:

  1. Un sitio en ASP.NET con varios User Controls.
  2. Los editores usan el CMS para crear nuevas páginas, y en tiempo de diseño pueden insertar los controles de usuario del proyecto de ASP.NET.
  3. En tiempo de diseño, el CMS no soporta ASP.NET.
  4. Cuando el editor envía a publicar las páginas, estas son copiadas dentro del sitio ASP.NET, donde recién el código ASP.NET podrá ser ejecutado.
  5. En tiempo de diseño del CMS, el editor debe poder ver el preview de los controles de ASP.NET.

Era una tarea bastante interesante, la cual de lo que me comentaron no se había podido realizar antes, por suerte con un poco C# se me ocurrió la siguiente idea:

Crear una página en el proyecto ASP.NET que reciba como parámetros el nombre del UserControl que se debe mostrar y los parámetros para inicializarlo, luego obtener el HTML resultante y devolverlo al cliente como una función JavaScript. De esta forma quien quiera mostrar un control de usuario en sitios no ASP.NET, solo necesita usar un poco de JavaScript (muy poco a decir verdad).

RenderControl.aspx

Esta es la página que recibe como parámetro en el QueryString el nombre del User Control y crea dinámicamente una función JavaScript con el HTML resultante. Adicionalmente el UserControl puede recibir parámetros de entrada como Strings, Booleanos, o números. Haciendo uso de Reflection, esta página se encarga de asignar dinámicamente estas propiedades antes de dibujar el control.

Creando los User Controls

Lo primero que haremos es crear unos 3 controles de usuario de ejemplo:

image AllUsers.ascx: Contiene un ASp.NET GridView con una lista de usuarios obtenida de un archivo XML.

 

 

image MyCalendar.ascx: Contiene un ASP.NET Calendar

 

 

 

 

 

image UserProfile.ascx: Muestra los datos de un usuario especificado, el usuario se asigna usando la propiedad Username, la cual lee de nu archivo XML los datos del usuario.

public string Username
        {
            set
            {
                lblUsername.Text = value;
                LoadProfile();
            }
            get
            {
                return lblUsername.Text;
            }
        }

              private void LoadProfile()
        {
            if (!String.IsNullOrEmpty(lblUsername.Text))
            {
                XDocument userXml = XDocument.Load(Server.MapPath("Data/Users.xml"));

                var userProfile = (from user in userXml.Descendants("user")
                                   where user.Attribute("id").Value == lblUsername.Text
                                   select user).Single();

                lblFirstname.Text = userProfile.Attribute("firstName").Value;
                lblLastname.Text = userProfile.Attribute("lastName").Value;
                lblRole.Text = userProfile.Attribute("role").Value;
            }
        }

image

Estos son User Controls normales, que pueden tener elementos ASP.NET cuyo HTML resultando será mostrado en otro sitio externo.

Crear la función JavaScript

Para que nuestra página RenderContro.aspx sea capaz de dibujar el control y devolver código JavaScript necesitamos sobreescribir dos métodos de la clase Page:

  1. CreateHtmlTextWriter
  2. Render

Si recordamos el ciclo de vida de una página ASP.NET: Init, Load, Render y Unload, nos damos cuenta de que justamente el método Render es el encargado de “dibujar en la página” el contenido:

StringWriter sw = new StringWriter();
HtmlTextWriter pageWriter = null;

protected override HtmlTextWriter CreateHtmlTextWriter(TextWriter tw)
        {
            pageWriter = base.CreateHtmlTextWriter(tw);
            return base.CreateHtmlTextWriter(sw);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(writer);
            string html = sw.ToString();
            html = html.Replace(Environment.NewLine, String.Empty);
            html = html.Replace("\"", "’");

            string script = "function render_" + controlName + uniqueId + "() { document.write(\"" + html + "\");}";

            pageWriter.Write(script);
        }

En el método CreateHtmlTextWriter estamos pasando un objeto StringWriter en lugar del predeterminado (TextWriter), es en este objeto donde el método Render insertará el código HTML de los controles. Todo el contenido de la página en forma de HTML, cualqueira que se este, será escrito dentro de nuestro  StringWriter, y posteriormente podremos manipularlo según nuestras necesidades.

En el método Render modificamos el HTML antes de que s dibuje en la página, de tal forma que el resultado sea una función JavaScript con el método document.write.

La función es creada dinámicamente y se forma de la siguiente forma:

  1. El prefijo “render_”
  2. El nombre del control.
  3. Un identificador único para el nombre de la función.
  4. El cuerpo de la función consiste del método document.write y el contenido es el HTML resultando de la página.

NOTA: Es siempre importante remover saltos de línea y comillas que del contenido puedan generar errores en la función JavaScript.

Insertar el control dinámicamente

La última parte de nuestro proyecto es insertar el control dinámicamente en la página para que se cree la función JavaScript. Insertar un control dinámicamente es muy sencillo en ASp.NET:

Control ctrl = LoadControl(@"~\UserControls\" + controlName + ".ascx");
canvas.Controls.Add(ctrl);

La parte interesante está en asginar las propiedades de forma dinámica a cada control. Por ejemplo asignar el valor de la propiedad Username de control UserProfile. Esto lo logré usando Reflection, gracias a esto puedo asignar el valor de cualqueir propiedad cuyo tipo de dato soporte el método Parse:

private void SetProperties(Control ctrl)
        {
            Type controlType = ctrl.GetType();
            List<PropertyInfo> properties =  controlType.GetProperties().ToList<PropertyInfo>();

            foreach (var qs in Request.QueryString)
            {
                if (!qs.ToString().Equals(qsControl, StringComparison.InvariantCultureIgnoreCase)
                    && !qs.ToString().Equals(qsUniqueId, StringComparison.InvariantCultureIgnoreCase))
                {
                    PropertyInfo currentProperty = properties.Find(delegate(PropertyInfo pi)
                    {
                        return pi.Name == qs.ToString();
                    });

                    if (currentProperty != null)
                    {
                        if (currentProperty.PropertyType.Name == "String")
                        {
                            currentProperty.SetValue(ctrl, Request.QueryString[qs.ToString()], null);
                        }
                        if (currentProperty.PropertyType.GetMember("Parse").Length > 0)
                        {
                            Object parsedValue = currentProperty.PropertyType.InvokeMember("Parse", BindingFlags.InvokeMethod, null, ctrl, new object[] { Request.QueryString[qs.ToString()] });
                            currentProperty.SetValue(ctrl, parsedValue, null);
                        }
                    }
                }
            }
        }

Este método recibe como parámetro el Control y lee del QueryString las propiedades que se le deben asignar mediante Reflection. De especial interés es el siguiente bloque de código:

if (currentProperty.PropertyType.GetMember("Parse").Length > 0)
                        {
                            Object parsedValue = currentProperty.PropertyType.InvokeMember("Parse", BindingFlags.InvokeMethod, null, ctrl, new object[] { Request.QueryString[qs.ToString()] });
                            currentProperty.SetValue(ctrl, parsedValue, null);
                        }

Esta sección de código permite transformar el valor de la propiedad que siempre viene como String al tipo de dato que espera la propiedad, por ejemplo Bool o Int. La transformación se la hace invocando dinámicamente el método Parse del tipo de datos de la propiedad.

Finalmente ya podemos incrustar controles ASP.NET en paginas desarrolladas en otras tecnologías, o páginas simples HTML, así:

<head>
    <title></title>
    <script src="RenderControl.aspx?control=UserProfile&Username=cintriago&UpperCase=true"></script>
    <script src="RenderControl.aspx?control=UserProfile&uniqueId=2&Username=jane"></script>
    <script src="RenderControl.aspx?control=UserProfile&uniqueId=3&Username=john"></script>
    <script src="RenderControl.aspx?control=AllUsers"></script>
    <script src="RenderControl.aspx?control=MyCalendar"></script>
</head>
<body>
<script language="javascript" type="text/javascript">        render_AllUsers();</script>
    <script language="javascript" type="text/javascript">        render_UserProfile();</script>
    <script language="javascript" type="text/javascript">        render_UserProfile2();</script>
    <script language="javascript" type="text/javascript">        render_MyCalendar();</script>
    <script language="javascript" type="text/javascript">        render_UserProfile3();</script>
</body>
</html>

Y en el navegador tendremos el siguiente resultado:

image Espero que este artículo les haya pareceido de utilidad en interés. Cualquier duda, comentario o sugerencia es bienvenida. Hasta la próxima!!.

Bajar el proyecto y código fuente

ASP.NET MVC 2 Preview 2 Liberado

Posted in ASP.NET, Microsoft, Noticias on octubre 1, 2009 by César Intriago

 

Ya está disponible hace unos momentos el Preview 2 de ASP.NET MVC 2 el cual pueden descargar desde aquí. Desde luego existe para toda la comundiad videos y documentación para conocer las nuevas características de este framework, entre las cuales destacan:

  1. ModelMetadata and ModelMetadataProvider Classes: Proveen mecanismos para obtener metadados del modelo de una vista.
  2. Model Validator Providers: Mecanismos para obtener la lógica de validación del modelo.
  3. Client-Side Validation: Incluye la librería de validación de jQuery 2 y también para el lado del cliente.
  4. RequireHttpsAttribute Action Filter: Nuevo atributo que puede ser aplicado a acciones y controladores. De forma predeterminada las peticiones no-SSL se redirigen a la llamada SSL equivalente (en el caso de estar disponible).
  5. Soporte para Single-Project Areas.

clip_image002

 

Les recomiendo que visiten el Roadmap de ASP.NET MVC para ver es lo nuevo que se viene!.

WCF y OperationBehaviors

Posted in ASP.NET, Microsoft, Patrones de Diseño, Tutorial on septiembre 30, 2009 by César Intriago

 

Windows Communication Foundation nos permite desarrollar servicios en .Net  de una manera rápida y sencilla, permitiendo soportar varios endpoints y esquemas de configuración. También ofrece un gran nivel de personalización, uno de ellos es poder escribir OperationBehaviors personalizados para nuestro servicio.

Un OperationBehavior nos permite cambiar y controlar el modo en que WCF ejecuta un método, por ejemplo podemos ejecutar código automáticamente antes de que se llame a una operación o después. Este es el caso que veremos en el siguiente ejemplo:

Creación del Servicio

Ok manos a la obra, lo primero es crear un nuevo proyecto WCF, el cual llamaremos “CalculatorService”

image

Luego agregamos dos operaciones a nuestro servicio, tanto en la interfaz como en la implementación: Add y Substract, como se ve en la siguiente figura:

image

Estas dos funciones lo que hacen es agregar y restar un valor de la variable de instancia _currentValue.

Ejecutamos el proyecto, y Visual Studio abrirá un cliente básico para poder probar nuestro servicio:

image

Behaviors

Ahora haremos algo interesante: Cada vez que se llame al método Add o Substract invocaremos de forma automática a un tercer método llamado “Audit”, esto lo hacemos usando OperationBehviors que nos permitirá tener acceso a personalizar la invocación de nuestros métodos.

En el proyecto de nuestro servicio WCF creamos una nueva carpeta llamada Behaviors ya agregamos una nueva clase llamada “MyOperationBehavior.cs” con el siguiente código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace CalculatorService.Behaviors
{
    public class MyOperationBehavior : Attribute, IOperationBehavior
    {

        #region IOperationBehavior Members

        public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation)
        {
        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
        {

// Decorator pattern.
            dispatchOperation.Invoker = new MyOperationInvoker(dispatchOperation);
        }

        public void Validate(OperationDescription operationDescription)
        {
        }

        #endregion
    }

    class MyOperationInvoker : IOperationInvoker
    {
        private readonly IOperationInvoker _invoker;
        private readonly System.ServiceModel.Dispatcher.DispatchOperation _dispatchOperation;

        public MyOperationInvoker(System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
        {
            this._invoker = dispatchOperation.Invoker;
            this._dispatchOperation = dispatchOperation;
        }

        private void HandleOperationRequest(object instance, object[] inputs)
        {
            Service1 srv = (Service1)instance;
            srv.Audit(_dispatchOperation.Name, inputs);
        }

        #region IOperationInvoker Members

        public object[] AllocateInputs()
        {
            return _invoker.AllocateInputs();
        }

        public object Invoke(object instance, object[] inputs, out object[] outputs)
        {
            HandleOperationRequest(instance, inputs);
            return _invoker.Invoke(instance, inputs, out outputs);
        }

        public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
        {
            HandleOperationRequest(instance, inputs);
            return _invoker.InvokeBegin(instance, inputs, callback, state);
        }

        public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            return _invoker.InvokeEnd(instance, out outputs, result);
        }

        public bool IsSynchronous
        {
            get { return _invoker.IsSynchronous; }
        }

        #endregion
    }
}

Ahora decoramos nuestros métodos Add y Substract con el atributo anterior y creamos el método “Audit”:

image

Lo que hemos hecho hasta el momento es crear una clase MyOperationBehavior que se encarga de conectar el MyOperationInvoker al servicio. Al aplicar el atributo  [MyOperationBehavior] en cada operación hacemos que WCF use nuestro Operation Invoker para llamar a las respectivas funciones.

Dentro de MyOperationInvoker estamos llamando primero al método Audit para imprimir en pantalla la operación que el usuario está a punto de ejecutar.

Esto nos da el control de poder ejecutar código adicional antes de que se ejecute el método que invocó el cliente (o incluso desués). Si volvemos a ejecutar el servicio podemos ver los resultados en la ventana “Output” de Visual Studio 2010.

image

Nota: Este mismo resultado se pudo obtener llamando desde los métodos Add y Substract al método Audit. Pero gracias a los OperationBehaviors podemos remover esta lógica de cada posible método que tengamos y ponerla en un solo lugar.

ASP.NET MVC eBook Gratis

Posted in ASP.NET, Microsoft, Noticias, Tutorial on abril 8, 2009 by César Intriago

 

bookcover1_6CAECF94Más buenas noticias de ASP.NET MVC !!. Scott Guthrie nos trae este eBook con un tutorial que cubre el desarrollo de NerdDinner, una aplicación ASP.NET MVC. Es un excelente material para aprender más de este tema y punto de referencia sobre la arquitectura de las aplicaciones.

<< Descargar el libro

A primer vistazo se explica brevemente un poco de la estructura de proyectos en MVC, y luego manos a la obra, código, código y más código!!.

Algo además interesante de mencionar es que el eBook se distribuye bajo la licencia Creative Commons.

Este fin de semana será el momento para darle una buena leída y empezar a escribir código, tocará darle descanso al Halo3 este fin de semana. Thanks Scott !.

Otros enlaces recomendados sobre material relacionado a ASP.NET MVC:

  1. http://www.asp.net/learn/mvc/#MVC_Overview
  2. http://aspnet.codeplex.com/Wiki/View.aspx?title=MVC&referringTitle=Home

Ya está disponible ASP.NET MVC

Posted in ASP.NET, Microsoft, Noticias on abril 4, 2009 by César Intriago

Finalmente fue liberada hace pocos días la versión final de ASP.NET MVC la cual pueden descargar desde la página de ASP.NET MVC:

http://www.asp.net/mvc/

Ya lo tengo instalado y la probaré en los siguientes días, antes había trabajado con otro patrón de diseño: el MVP que me pareció muy bueno; ahora voy a probar el ASP.NET MVC a ver que tal, hay buenos ejemplos, videos y documentación en la página oficial.

ASP.NET MVC

De MVC puedo decir que facilita mucho el tema de SEO (Search Engine Optimization) para tener URLs “amigables” y mas control en la parte del front-end.