Autor en Google+
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 ;)

15 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, 17 de junio de 2008
Visual Studio Logo
Cuando hace unas semanas ScottGu anunció la Preview 3 de ASP.NET MVC, quedé muy sorprendido de que al final no viniera con soporte para Visual Web Developer Express 2008, sobre todo teniendo en cuenta que un mes antes había adelantado este acontecimiento para los que estamos probando la plataforma MVC con esta herramienta.

Pero no, era una falsa alarma. Scott había olvidado comentarlo, y días más tarde rectificaba en un nuevo post en el que comunicaba que sí sería posible usar la Preview 3 desde la versión Express de Web Developer sin necesidad de usar plantillas específicas.

Desde entonces estaba deseando tener un ratillo para probarlo, y por fin ha llegado el momento.

En primer lugar, he de aclarar que, aunque pueda parecer lo contrario, no se trata de que el equipo de Microsoft haya introducido cambios en la plataforma MVC para hacerla compatible con la versión Express, sino al revés. Son los nuevos cambios introducidos en el IDE, y principalmente su recién estrenado soporte a proyectos de tipo Aplicación Web, los que hacen posible que funcione directamente sobre esta herramienta.

Y este es el motivo de que, antes que nada, sea necesario instalar el SP1 de .NET Framework 3.5 y de las herramientas Express (aún en Beta). Y si váis a hacerlo, mucho ojo, que todas las páginas donde aparece para descargar aparece llena de warnings; en otras palabras, no recomiendan su instalación en máquinas de verdad, sólo en entornos de prueba. Pero no os preocupéis, que para eso estoy yo ;-)

Después de un proceso algo lento y un par de reinicios del equipo, el Service Pack 1 Beta queda instalado sin problemas. Sólo falta descargar y montar la Preview 3 de ASP.NET MVC para que al ir a crear un nuevo proyecto desde Visual Web Developer aparezcan la plantilla MVC, entre otras novedades:

Plantillas disponibles en Web Developer Express 2008 con SP1 Beta

Y para probar, nada mejor que la aplicación de demostración sobre Northwind que preparó Phil Haack hace unas semanas. Salvo un ligero error de carga debido a que la versión Express no soporta la creación de proyectos de solución (no podremos probar los tests unitarios integrados en VS2008), todo funciona a la perfección.

Northwind demo para MVC CTP 3

Sí señor. Ahora sí que podemos seguir jugando. :-)

Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

miércoles, 11 de junio de 2008
PuzzleAunque es lo que más mola, los desarrolladores no siempre podemos trabajar con los últimos lenguajes y tecnologías. De hecho, solemos pasar gran parte de nuestro tiempo manteniendo y mejorando sistemas basados en plataformas que consideramos obsoletas o de menor potencia que las habituales, lo que nos lleva a tener que dar respuesta "artesana" a problemas que usando tecnologías más apropiadas estarían solucionados.

Hoy por ejemplo, desarrollando con VbScript en un entorno propietario embebido en un sistema de gestión empresarial hemos necesitado crear GUIDs y hemos visto que el lenguaje no dispone de esta capacidad, a diferencia de .Net o Java, que proporcionan vías para conseguirlo de forma muy sencilla.

Preguntándole a Google, que todo lo sabe, he encontrado varias soluciones aplicables de forma directa.

La primera, es usar funciones propias del motor de base de datos. En nuestro caso concreto, la solución está conectada a un SQL Server, que afortunadamente dispone desde la versión 2000 de una función integrada de generación de GUIDs. Así pues, podríamos utilizar un código como el siguiente:
' Obtiene un nuevo GUID
' Parámetro: una conexión abierta
function ObtenerGUID(conn)
dim rs
set rs = conn.Execute("Select NEWID()")
if (not rs.eof) then
ObtenerGUID = rs(0)
end if
end function
 
Pero, ¿y si no usas SQL Server? No pasa nada, prácticamente todos los motores de bases de datos incorporan algún mecanismo equivalente, como MySQL ("UUID()") y Oracle ("SYS_GUID()").

En este momento podríamos decir que tenemos una buena solución... siempre que tengamos a mano una conexión a una base de datos capaz de generar un GUID. ¿Y si no fuera este el caso? Aquí va otro código que utilizando un objeto Scriptlet.TypeLib, utilizado por Windows como soporte a los lenguajes de scripting:
' Obtiene un nuevo GUID
Function ObtenerGUID()
dim typeLib, guid
set typeLib = CreateObject("Scriptlet.TypeLib")
guid = typeLib.Guid
ObtenerGUID= left(guid, len(guid)-2)
set typeLib = Nothing
End Function
 
También hay quien utiliza llamadas a UUIDGEN.EXE, una utilidad proporcionada normalmente con kits de desarrollo de .NET y los entornos Visual Studio, generando el GUID sobre un archivo de texto para más tarde leerlo desde el script, pero me ha parecido una solución demasiado compleja para el problema.

Por último he encontrado unos ejemplos de código en el centro de soporte de Microsoft que muestran varias maneras de crear identificadores únicos, aunque me quedo con la más completa, consistente en generar la secuencia de caracteres aleatorios:
' Obtiene un GUID tipo Windows
' 8+4+4+4+12 caracteres A-Z y 0-9
Function CreateWindowsGUID()
CreateWindowsGUID = CreateGUID(8) & "-" & _
CreateGUID(4) & "-" & _
CreateGUID(4) & "-" & _
CreateGUID(4) & "-" & _
CreateGUID(12)
End Function

' Obtiene un GUID del tamaño indicado
' Parámetro: longitud del GUID
Function CreateGUID(tmpLength)
Randomize Timer
Dim tmpCounter,tmpGUID
Const strValid = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
For tmpCounter = 1 To tmpLength
tmpGUID = tmpGUID & Mid(strValid, Int(Rnd(1) * Len(strValid)) + 1, 1)
Next
CreateGUID = tmpGUID
End Function


Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

domingo, 8 de junio de 2008
Cuestiones enviadas por lectoresRespondiendo a una consulta que hacía Joaquín hace un par de días, hoy describiremos una forma de hacer más atractivos los cuadros de edición de nuestros formularios web, introduciéndoles iconos o imágenes que, a la vez que adornan bastante, pueden ayudar al usuario a saber qué información debe introducir.

Pero para que quede claro lo que pretendemos, primero un ejemplo del resultado que vamos a conseguir:


La forma de conseguirlo es bastante sencilla. Basta con establecer, en las propiedades de estilo de los cuadros de edición una imagen de fondo con el icono que queremos incluir, y dejar un espaciado por la izquierda (padding-left) equivalente al ancho del mismo para que la introducción del texto comience a partir de ese punto.

Por ejemplo, si definimos las siguientes clases en el CSS de nuestra página (y suponiendo que la ruta de las imágenes sea correcta, claro):
 .lupa
{
background: white url(icono_lupa.gif) no-repeat 2px center;
padding: 2px 2px 2px 18px;
}
.telefono
{
background: white url(icono_telefono.gif) no-repeat 2px center;
padding: 2px 2px 2px 18px;
}
 
Como se puede observar, se establece un fondo blanco con una imagen cuya URL se especifica (icono_xxxx.gif), mostrada sin repetición (no-repeat), posicionada en coordenada horizontal 2px y centrada verticalmente. El padding izquierdo será de 18px para que comience ahí el área de edición, a la derecha de la imagen.

Podremos utilizar después en nuestro HTML un código como el siguiente para conseguir que los cuadros de edición apararezcan "adornados" como nos interese en cada momento eligiendo para cada uno de ellos la clase CSS apropiada:
 <input type="text" class="lupa" />
<input type="text" class="telefono" />
 
Espero que esto responda la duda, Joaquín.

Y por cierto, he utilizado esta técnica en el buscador del encabezado del blog, que lo tenía un poco soso...

Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

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.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

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.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

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.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons