Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 3 de junio de 2008
Ya comenté un día mi fascinación por los motores de física en tiempo real. Siguiendo con este tema, os voy a presentar hoy otro engine con el que me he topado.

Box2DFlashAS3 es un port para ActionScript 3.0 de una librería originalmente escrita para C++, Box2D. Ahí van unas demostraciones de sus posibilidades (pulsad las teclas izquierda y derecha para cambiar la demo, "R" para resetear la vista y también podéis arrastrar objetos con el ratón):

Hace unos meses se publicó su última revisión, la 4.1.3, y se distribuye bajo licencia zlib/libpng, lo que permite su libre utilización incluso con fines comerciales.

Publicado en: www.variablenotfound.com.
lunes, 2 de junio de 2008
Eilon Lipton, miembro del equipo de desarrollo de ASP.NET e involucrado en la actualidad en la creación del framework ASP.NET MVC, publicó hace unos meses en su post ASP.NET MVC Design Philosophy "la serpiente MVC", un nombre muy gráfico para el diagrama que utilizó en la presentación realizada en el evento DevConnections junto a Scott Hanselman para explicar el ciclo de vida de una petición bajo este nuevo marco de trabajo:

La serpiente ASP.NET MVC

[ING] ASP.NET Page Life Cycle en blog de Kris Van Der MastComo se puede observar, el recorrido que sigue una petición desde que se produce hasta que se envía la respuesta de vuelta es bastante simple, aunque como comenta Eilon, hay algunas (pocas) fases más que no se han mostrado por claridad del diagrama.

Entre otras cosas, se pone de manifiesto la simplicidad de este modelo frente al complejo ciclo de vida de una página utilizando la tecnología Webforms.

Y por cierto, podéis descargar la presentación completa que realizaron en el DevConnections, aunque eso sí, en inglés.

Publicado en: www.variablenotfound.com.
domingo, 1 de junio de 2008
[ING] Ir al sitio web de jQueryMuy interesante el artículo Using jQuery to directly call ASP.NET AJAX page methods, en el que se demuestra que es posible, y además realmente sencillo, invocar métodos estáticos de página (PageMethods) utilizando esta magnífica librería javascript.

Como ya sabemos los PageMethods son métodos estáticos definidos dentro de la clase de una página, es decir, en su codebehind, y que son accesibles desde cliente utilizando Ajax (en minúsculas!).

Hace más de un año ya estuve comentando cómo hacerlo utilizando la propia infraestructura de ASP.NET Ajax y sus librerías de scripting para hacerlo muy fácilmente. De forma muy breve, todo consistía en crear el método estático al que se deseaba acceder, decorarlo con el atributo WebMethod, e incluir en la página un ScriptManager con estableciéndole la propiedad EnablePageMethods=true; a partir de ese momento, podíamos invocarlo desde cliente usando javascript de forma muy directa.

Sin embargo, el uso de estándares como JSON hace posible la invocación de WebMethods desde scripting sin necesidad de recurrir a la magia del ScriptManager. De hecho, y como vamos a ver más adelante, vamos a realizar la llamada al método utilizando Ajax desde una página HTML pura, sin controles de servidor ni otros edulcorantes proporcionados por ASP.NET.

Desarrollaremos un ejemplo completo (esta vez en VB.NET, por cambiar un poco), que demuestre cómo podemos crear un PageMethod en una página (default.aspx), e invocarlo desde otra (pagina.htm) usando la librería jQuery para comunicar ambos componentes.

1. Definición del PageMethod

Como ya comenté en el post al que hacía referencia antes, un PageMethod se define en la clase asociada a una página .aspx (su code-behind) y es un método normal y corriente, aunque obligatoriamente será estático y público. Además, debe presentar el atributo WebMethod(), que lo identifica como accesible a través llamadas HTTP.

El siguiente código muestra el PageMethod que vamos a utilizar. Se supone que partimos de una página Default.aspx totalmente vacía (de hecho, no vamos a crear nada más dentro), y que el siguiente código corresponde al archivo Default.aspx.vb:
Imports System.Web.Services

Partial Public Class _Default
Inherits System.Web.UI.Page

<WebMethod()> _
Public Shared Function Saludame(ByVal Nombre As String) As String
Return "Hola a " + Nombre _
+ " desde el servidor, son las " _
+ DateTime.Now.ToString("hh:mm:ss")

End Function
End Class
 
Se puede observar que el método recibirá un parámetro, el nombre del destinatario del mensaje de saludo. Una vez que lo tenemos definido de esta forma, siempre que el proyecto esté correctamente configurado, el método es accesible en la dirección "Default.aspx/Saludame" para todo aquél que quiera utilizarlo, siempre que siga ciertas reglas.

2. Creamos la página "cliente"

Interfaz del ejemploPara probar la invocación al método definido anteriormente montaremos un interfaz muy simple, un cuadro de edición en el que el usuario introducirá un nombre y un botón que solicitará al servidor el saludo. Las sucesivas respuestas se irán añadiendo al final de la página, tras la etiqueta "Mensajes obtenidos".

En lugar de mostrar el código fuente de la página HTML (pagina.html) completo, voy a hacerlo por partes, y saltándome algunas porciones que no tienen demasiado interés. En primer lugar va la correspondiente al interfaz, que es bastante simple:
<body>
<form>
<input type="text" id="nombre" />
<input type="button" value="¡Pulsa!"
onclick="llamar();" />
<br />
<strong>Mensajes obtenidos:</strong><br />
<label id="lblMensajes" />
</form>
</body>
 
Como se puede intuir, la función llamar(), invocada al hacer click sobre el botón, será la que realice la conexión con el servidor, le envíe el nombre contenido en el cuadro de edición, e introduzca la respuesta en la etiqueta lblMensajes, que actuará como contenedor.

Vamos ahora con la porción de página donde se desarrolla la acción. Primero se incluye jQuery en la página, y acto seguido creamos la función llamar() que hemos comentado anteriormente:
<script type="text/javascript" 
src="scripts/jquery-1.2.6.min.js" ></script>
<script type="text/javascript">
function llamar()
{
$.ajax({
type: "POST",
data: "{ Nombre: '" + $("#nombre").val() + "'}" ,
url: "Default.aspx/Saludame",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
$("#lblMensajes").append(msg);
$("#lblMensajes").append("<br />");
},
error: function(msg) { alert("Algún problema debe haber..."); }
});
}
</script>
 
Los parámetros de llamada a la función ajax() de jQuery son los siguientes:
  • type, la petición HTTP es de tipo POST. Es obligatorio para acceder a los PageMethods por motivos de seguridad.
  • data contiene una representación JSON de los parámetros enviados al método. En este caso, vemos que se compone de forma dinámica inyectándole el valor del cuadro de edición (obtenido a su vez utilizando un selector jQuery y el método val()). Fijaos que esta representación define un objeto anónimo cuyas propiedades deberán coincidir con los parámetros del método; para este ejemplo, un valor correcto de data sería "{ Nombre: 'Juan' }".
  • url contiene la dirección del método. Observad que es el nombre de la página seguido del nombre del método.
  • El content-type indica el tipo de contenido que enviamos al servidor; en este caso, dado que le vamos a enviar JSON codificado en utf-8 debe ser "application/json; charset=utf-8".
  • Con dataType indicamos al servidor qué tipo de respuesta estamos esperando. Dado que la trataremos también desde script, será más sencillo si es JSON.
  • success contiene una función anónima que recibe como parámetro la respuesta del servidor. En este caso, hemos implementado su inclusión en la etiqueta que habíamos preparado para mostrar los mensajes del servidor.
  • de la misma forma, en error implementamos lo que queremos que haga el sistema cuando se produzca un problema. En este caso sólo avisamos.

Y... ¡listo para funcionar!

Fijaos en un detalle importante: nada impide la invocación de PageMethods desde páginas distintas a donde se han definido, cosa que con el comportamiento estándar del ScriptManager y su EnablePageMethods=true sería imposible.

Finalmente, recordar que para que todo esto funcione el proyecto web debe estar correctamente configurado para trabajar con las extensiones Ajax. Las plantillas de proyectos de Visual Studio 2008 ya vienen preparadas de forma predeterminada, pero si usas VS2005 deberás crear el proyecto usando las plantillas para aplicaciones Web con Ajax, o retocar a mano el web.config.

Puedes descargar el proyecto de prueba para VS2005.

Publicado en: www.variablenotfound.com.
domingo, 25 de mayo de 2008
¿A qué huele tu código?Algunos dirán que a nada, como las nubes ;-) Sin embargo, el olor que desprende tu código, el llamado "code smell", término acuñado por Kent Beck (uno de los padres del Extreme Programming), puede darte pistas sobre problemas existentes en el mismo y alertarte ante situaciones no deseadas.

El concepto es parecido a los antipatrones de programación, aunque funcionan a un nivel todavía más sutil, pues no describe situaciones completas sino indicios. De hecho, el uso de esta metáfora sensorial respecto a un código, es decir, que éste desprenda cierto tufillo, indica que sería conveniente realizar una revisión en profundidad para ver si hay que refactorizar, pero no implica que necesariamente haya algo incorrecto. Además, dado que trata de algo tan personal y específico como el código fuente, a veces las señales son bastante subjetivas y dependientes de lenguajes y tecnologías concretas.

Existen multitud de listas y clasificaciones, aunque es muy interesante la realizada por Mika Mäntylä, investigador de la universidad de Helsinki, ha creado una taxonomía que agrupa code smells relacionados en cinco categorías en función del efecto que pueden provocar:

  • The bloaters (los infladores), que agrupa 'aromas' que indican el crecimiento excesivo de algún aspecto que hacen incontrolable el código.

    • Long method (método extenso) que precisa de su reducción para ser más legible y mantenible.

    • Large class (clase larga), con síntomas y consecuencias muy similares al caso anterior.

    • Primitive obsession (obsesión por tipos primitivos), cuyo síntoma es la utilización de tipos primitivos para almacenar datos de entidades pequeñas (por ejemplo, usar un long para guardar un número de teléfono).

    • Long parameter list (lista de parámetros larga), que incrementan la complejidad de un método de forma considerable.

    • Dataclumps (grupos de datos), o uso de un cunjunto de variables o propiedades de tipos primitivos en lugar de crear una clase apropiada para almacenar los datos, lo que a su vez provoca el incremento de parámetros en métodos y clases.

  • The Object-Orientation Abusers (los maltratadores de la orientación a objetos), que aglutina code smells que indican que no se está aprovechando la potencia de este paradigma:

    • Switch statements (sentencias Switch), que podrían indicar una falta de utilización de mecanismos de herencia.

    • Temporary field (campo temporal), que se salta el principio de encapsulamiento y ocultación de variables haciendo que éstas pertenezcan a la clase cuando su ámbito debería ser exclusivamente el método que las usa.

    • Refused bequest (rechazo del legado), cuando una subclase 'rechaza' métodos o propiedades heredadas, atentando directamente contra uno de los principales pilares de la OOP.

    • Alternative Classes with Different Interfaces (clases alternativas con distintos interfaces) indica la ausencia de interfaces comunes entre clases similares.

  • The change preventers (los impedidores de cambios)

    • Divergent Change (cambio divergente), que hace que sean implementadas dentro de la misma clase funcionalidades sin ninguna relación entre ellas, lo que sugiere extraerlas a una nueva clase.

    • Shotgun surgery (cirujía de escopeta), ocurre cuando un cambio en una clase implica modificar varias clases relacionadas.

    • Parallel Inheritance Hierarchies (jerarquías de herencia paralelas), paralelismo que aparece cuando cada vez que se crea una instancia de una clase es necesario crear una instancia de otra clase, evitable uniendo ambas en una úncia clase final.


  • The Dispensables (los prescindibles), pistas aportadas por porciones de código innecesarias que podrían y deberían ser eliminadas:

    • Lazy class (clase holgazana), una clase sin apenas responsabilidades que hay que dotar de sentido, o bien eliminar.

    • Data class (clase de datos), cuando una clase sólo se utiliza para almacenar datos, pero no dispone de métodos asociados a éstos.

    • Duplicate code (código duplicado), presencia de código duplicado que dificulta enormemente el mantenimiento.

    • Dead code (código muerto), aparición de código que no se utiliza, probablemente procedente de versiones anteriores, prototipos o pruebas.

    • Speculative generality (generalización especulativa), ocurre cuando un código intenta solucionar problemas más allá de sus necesidades actuales.


  • The couplers (Los emparejadores), son code smells que alertan sobre problemas de acoplamiento componentes, a veces excesivo y otras demasiado escaso.

    • Features envy (envidia de características), que aparece cuando existe un método de una clase que utiliza extensivamente métodos de otra clase y podría sugerir la necesidad de moverlo a ésta.

    • Inappropriate intimacy (intimidad inapropiada), ocurre cuando dos clases de conocen demasiado y usan con demasiada confianza, y a veces de forma inapropiada, sus miembros (en la acepción POO del término ;-))

    • Message Chains (cadenas de mensajes), aroma desprendido por código que realiza una cadena de llamadas a métodos de clases distintas utilizando como parámetros el retorno de las llamadas anteriores, como A.getB().getC().getD().getTheNeededData(), que dejan entrever un acoplamiento excesivo de la primera clase con la última.

    • Middle man (intermediario), que cuestiona la necesidad de tener clases cuyo único objetivo es actuar de intermediaria entre otras dos clases.


Aunque agrupadas bajo otros criterios, existe una interesante relación de code smells y la refactorización a aplicar en cada caso, que ayuda a determinar las acciones correctivas oportunas una vez se haya comprobado que hay algo que no va bien.

Y ahora, ¿piensas que tu código no huele a nada? ;-P

Publicado en: http://www.variablenotfound.com/.
sábado, 24 de mayo de 2008
Análisis de CódigoJason Allor anunciaba ayer mismo el lanzamiento de una nueva herramienta, Microsoft Source Analysis for C#, cuyo objetivo es ayudar a los desarrolladores a producir código elegante, legible, mantenible y consistente entre los miembros de un equipo de trabajo. De hecho, era conocida como StyleCop en Microsoft, donde llevan utilizándola ya varios años.

Y aunque pueda parecer similar a FxCop, Microsoft Source Analysis for C# se centra en el análisis de código fuente y no en ensamblados, lo que hace que pueda afinar mucho más en las reglas de codificación.

Incluye sobre 200 buenas prácticas, cubriendo aspectos como:
  • Layout (disposición) de elementos, instrucciones, expresiones y consultas
  • Ubicación de llaves, paréntesis, corchetes, etc.
  • Espaciado alrededor de palabras clave y operadores
  • Espaciado entre líneas
  • Ubicación de parámetros en llamadas y declaraciones de métodos
  • Ordenación de elementos de una clase
  • Formateo de documentación de elementos y archivos
  • Nombrado de campos y variables
  • Uso de tipos integrados
  • Uso de modificadores de acceso
  • Contenidos permitidos en archivos
  • Texto de depuración
Microsoft Source Analysis integrado en VS2005
Tras su descarga e instalación, que puede realizarse desde esta dirección, la herramienta se integra en Visual Studio 2005 y 2008, aunque también puede utilizarse desde la línea de comandos o MSBuild.


Publicado en: www.variablenotfound.com.