¿Donde están los proyectos Web "clásicos" en el SP1 de VS2005?

Como ya he comentado en diversas ocasiones aquí, existe un complemento para Visual Studio que permite crear aplicaciones Web con el modelo de compilación clásico de ASP.NET 1.x. Ello permite migrar mejor las aplicaciones antiguas y además, algunos lo preferimos por su mayor claridad a la hora de desplegar, etc…


El caso es que el complemento que se podía descargar hasta hace unos días funcionaba sólo en la versión en inglés de Visual Studio 2005, pero ahora viene incluido en el Service Pack 1 de VS2005, tal y como comenté ayer, y por lo tanto está plenamente soportado por Microsoft y funciona en todos los idiomas de VS incluyendo el español.


El caso es que, tras instalar el SP1 creí que en «Nuevo Proyecto Web» habría alguna plantilla del estilo «Sitio Web ASPX clásico» o algo así, y no lo encontraba.


Para acceder a este tipo de proyectos debemosir por «Nuevo proyecto», normal, fuera de Visual Web Developer, y se nos muestran dos nuevas opciones tal y como pasaba en las versiones anteriores de Visual Studio, es decir, sin distinguir entre proyectos normales y proyectos Web:



Está dentro del lenguaje elegido, igual que antes, lo cual me parece la mar de coherente 🙂


Un acosa: ¿alguien ha instalado el SP1 en la versión Express de Visual Web Developer? Si es así: ¿se añaden este tipo de proyectos de compatibilidad? y siendo así ¿en dónde están?. Comentádmelo abajo. Gracias.

Botón y foco por defecto en páginas ASP.NET 2.0

Un par de novedades sencillas pero muy útiles que proporciona ASP.NET 2.0 son el botón y el foco por defecto.


Ahora podemos hacer que, pulsar ENTER en un formulario, sea equivalente a hacer clic en un determinado botón. Para ello basta con establecer el atributo defaultbutton en el formulario de nuestro archivo ASPX:



<form defaultbutton=“Boton1” runat=server>


Lo más interesante de esto y que no todo el mundo sabe es que, además, se puede especificar esta misma propiedad en los paneles (controles <asp:panel>) para especificar lo mismo para los controles que hay en su interior:



<asp:panel defaultbutton=“Boton2” runat=server>


Así, cuando tengamos el foco en un control dentro del panel, al pulsar ENTER es como si se pulsase el botón especificado. Esto sobreescribe el comportamiento especificado para el formulario pero sólo dentro del panel, lo cual puede ser muy útil sobre todo si ponemos varios para propósitos diferentes.


También existe un nuevo atributo del formulario llamado deafultfocus, con el que conseguiremos que un determinado control tenga el foco nada más cargar la página ASPX. De este modo nos evitamos el tener que establecerlo con JavaScript, aunque también podríamos establecerlo en el evento Load() con el método Focus() del control en cuestión o con el método SetFocus() de la página.

Componentes duales para Windows y la Web

¿Cómo puedo construir un componente o una biblioteca de clases que me sirva indistintamente para Windows Forms y para ASP.NET si debo usar características específicas de cada entorno?


Expresado con otras palabras: ¿Cómo puedo saber si mi componente está siendo usado desde una aplicación de Windows Forms o de ASP.NET?


Respuesta: verifica el valor de HttpContext.Current.


Si es null (Nothing en VB) es que estás en un entorno no-web, y estarás bajo ASP.NET en caso contrario.


Es un truco sencillo pero que a alguno puede que le resulte útil si se lo había planteado para algún componente propio.

Estadísticas de consultas SQL Server desde ADO.NET 2.0

La clase SqlConnection de ADO.NET 2.0 posee una característica que puede resultar de utilidad en cuertas ocasiones y que permite obtener información estadística sobre las consultas realizadas, de manera muy similar a la que ofrece el Analizador de consultas de SQL Server 2000 o el Management Studio de SQL Server 2005 (si bien no son las mismas).


Esta característica es muy fácil de gestionar gracias a la propiedad StatisticsEnabled de la clase SqlConnection, que sirve como es obvio para habilitar la recogida de estadísticas de las consultas lanzadas a través del objeto SqlConnection instanciado para la ocasión.


Una vez habilitadas las estadísticas se obtienen mediante el método RetrieveStatistics de la misma clase. Éste devuelve un objeto que implementa la interfaz IDictionary, aunque en realidad un poco de reflexión revela que realmente lo que se obtiene es un HashTable, así que es muy fácil de manejar (ahora lo veremos).


El método UpdateStatistics las actualiza al momento actual. Por fin el método ResetStatistics inicializa las estadísticas de esa conexión.


Veamos cómo funcionan y qué datos devuelven con un ejemplo. Para ello he creado rápidamente un proyecto de consola que lanza una consulta simple a la conocida base de datos Northwind y muestra las estadísticas por pantalla:



using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;

public class EstadisticasSQL
{
    public static void Main()
    {
        SqlConnection conn = new SqlConnection(@»server=.SQL2000;Integrated Security=SSPI;Database=Northwind;»);
        conn.StatisticsEnabled = true;
        SqlCommand cmd = new SqlCommand(«SELECT * FROM Customers», conn);
        try
        {
            conn.Open();
            SqlDataReader dr = cmd.ExecuteReader();
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        
        //Recojo las estadísticas
        Hashtable htStats = (Hashtable) conn.RetrieveStatistics();

        Console.WriteLine(«ESTADÍSTICAS DE LA CONSULTA:»);
        Console.WriteLine();
        foreach (string stat in htStats.Keys)
        {
            Console.WriteLine(«- « + stat + » = « + htStats[stat].ToString() );
        }

        conn.Close();
        Console.ReadLine();
    }
}


Lo que este código arroja por pantalla es lo siguiente:



Como vemos hay bastante información y tal vez la más interesante sea el tiempo que se ha esperado a la respuesta del servidor (NetworkServerTime), los bytes recibidos en forma de paquetes TDS (BytesReceived), el tiempo de ejecución (ExecutionTime) y el número de transacciones (Transactions), aunque cada uno en su caso sabrá qué le interesa.


Otra cosa: no es necesario estar atacando una base de datos SQL Server 2005 para que funciones, basta con usar ADo.NET 2.0. En el ejemplo como puedes comprobar por la cadena de conexión estoy usando un SQL Server 2000 y va estupendamente 🙂

El operador doble interrogación en C#

Los tipos anulables en .NET 2.0 son una interesante característica a la que se le puede sacar bastante partido, como ya expliqué en su momento.


Quiero comentar ahora una cosa que se me pasó entonces: el operador doble interrogante (??), el cual es además muy poco conocido.


Dado que los tipos anulables pueden contener un valor o un nulo debemos realizar continuamente comprobaciones en el código para ver si tenemos nulos o no, algo así (ej.):



int? num1 = 5; //En la realidad lo obtendríamos de una BD o algo así
int num2;
if (num1 == null)
   num2 = 0;
else
   num2 = num1;


Lo cual es sencillo pero es un rollo de escribir si hay que hacerlo continuamente. Claro que podemos reducir el código usando el operador ? de toda la vida de C#:



int? num1 = 5;
int num2 = (num1==null)?0:num1;


Es idéntico, más reducido, pero tampoco es mejore mucho la legibilidad ¿verdad?


Bien, C# nos ofrece el operador ?? que hace exactamente lo mismo que lo anterior y tiene las virtudes de ser conciso y a la vez legible (si sabes qué siginifica la doble interrogación, claro). Lo anterior quedaría con este operador así:



int? num1 = null;
int num2 = num1??0;


Es fácil de leer si lo interpretas así: asignar a num2 el valor de num1 o un cero si es nulo. Muy útil. Espero que lo disfrutes si no lo conocías :-))