3.15.2009

Como agregar un binding TCP de forma programada a un sitio web en IIS 7.0

La información del binding en un sitio web es indispensable para indicar cuales protocolos pueden ser utilizados para comunicarse con el sitio Web. En el contexto de WCF esto significa, que tipos de protocolos vamos a poder utilizar para consumir los servicios desarrollados en WCF y hosteados en IIS 7.0 y WAS.

En días pasados conversando con algunas personas que usan IIS 7.0 para hostear servicios en WAS utilizando el protocolo TCP, me preguntaron como agregar el binding de TCP a un sitio web utilizando el API de IIS 7.0 y C#. La consulta me pareció muy útil por que permite crear instaladores que hagan deploy de los servicios de forma transparente, incluso creando sus sitios webs a la hora de la instalación y agregando el binding deseado con este instalador. Aquí esta la solución a esta consulta.

Primeramente, vamos ver que es lo que necesitamos para tener el protocolo TCP habilitado en el sitio web. Para esto, en el archvio applicationHost.config  existe la sección bindings la cual existe por sitio web definido y tiene el siguiente formato:

<bindings>
    <binding protocol="http" bindingInformation="*:80:" />
    <binding protocol="net.tcp" bindingInformation="808:*" />
    <binding protocol="net.pipe" bindingInformation="*" />
    <binding protocol="net.msmq" bindingInformation="localhost" />
    <binding protocol="msmq.formatname" bindingInformation="localhost" />
</bindings>

Como podemos ver en el elemento XML anterior, existe una etiqueta binding para cada protocolo que queremos soportar en el sitio web. Además, cada elemento tiene dos atributos: protocol y bindginInformation. El protocolo define el protocolo que se utiliza para comunicarse con el sitio web, y el bindingInformation contiene la dirección IP, el número del puerto y opcionalmente el host header para el sitio web.

Para poder agregar TCP al sitio web deseado debemos primeramente buscar el elemento que contiene los sitios web en el archivo de configuración del servidor, seguidamente buscamos el sitio web deseado, y procedemos a agregarle el binding. El código para esta operación es el siguiente:

public static void AgregarBindiingASitioWeb( string nombreSitioWeb, string protocolo, string bindingInformation )
{
using (ServerManager server = new ServerManager( ))
{
Configuration hostConfiguration = server.GetApplicationHostConfiguration( );
ConfigurationSection sitesSection = hostConfiguration.GetSection("system.applicationHost/sites"); //utilizamos XPath para obtener el elemento
ConfigurationElementCollection sitesCollection = sitesSection.GetCollection( ); //Obtenemos todos los sitios web en el archivo
//Buscamos el sitio web deseado
ConfigurationElement siteElement = FindElement(sitesCollection, "site", "name", @nombreSitioWeb);
//Si no existe, lanzamos una excepción y abortamos el método.
if (siteElement == null) throw new InvalidOperationException("Sitio no encontrado!");
//Obtenemos la configuración del binding del sitio web
ConfigurationElementCollection bindingsCollection = siteElement.GetCollection("bindings");
//Creamos un elemento de binding para el sitio y le establecemos los valores deseados
ConfigurationElement bindingElement = bindingsCollection.CreateElement("binding");
bindingElement["protocol"] = @protocolo;
bindingElement["bindingInformation"] = @bindingInformation;
//Agregamos el binding a la colección de bindings del sitio web
bindingsCollection.Add(bindingElement);
//Guardamos los cambios en el archivo applicationHost.config
server.CommitChanges( );
}
}


private static ConfigurationElement FindElement( ConfigurationElementCollection collection, string elementTagName, params string[] keyValues )
{
//Iteramos sobre la coleccion de elementos para buscar la etiqueta site que tenga en el atributo
//name el valor pasado por parámetro
foreach (ConfigurationElement element in collection)
{
//Si el elemento encontrado es el sitio
if (String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase))
{
bool matches = true;
//Entonces buscamos el atributo deseado
for (int i = 0; i < keyValues.Length; i += 2)
{
object o = element.GetAttributeValue(keyValues[i]);
string value = null;
if (o != null)
{
value = o.ToString( );
}
if (!String.Equals(value, keyValues[i + 1], StringComparison.OrdinalIgnoreCase))
{
matches = false;
break;
}
}
if (matches)
{
return element;
}
}
}
return null;
}


El código para llamar al método de crear binding es:



AgregarBindiingASitioWeb("MiNuevositioWeb", "net.tcp", "808:*");



Antes de ejecutar el código anterior, el elemento Site de MiNuevoSitioWeb lucía así:



image Después de ejecutar el código anterior el resultado es:



imageComo podemos ver en la figura anterior, el binding para TCP se agregó al elemento del sitio web solicitado.

3.08.2009

Eclipse y Silverlight

Normalmente, cuando pensamos en silverlight pensamos en .NET. Resulta ser, que una empresa francesa en conjunto con Microsoft, desarrolló un plug in para Eclipse que permite desarrollar aplicación silverlight utilizando Java.

El articulo que nos muestra que contiene este plug in se puede ver en el sitio de la empresa que desarrolla el plug in. Los pasos para utilizar este plug in con eclipse se pueden ver en el blog de somasegar en el msdn.

También es interesante destacar un producto llamado eFace de esta empresa, que permite desarrollar UI’s utilizando XAML en Java. El link de este producto – el cual tiene una versión gratuita – se puede ver acá.

3.02.2009

Utilizando el API de IIS 7 para crear Web Sites Aplicaciones, Directorios Virtuales y para explorar mi servidor Web desde .NET

En días pasados tuve la necesidad de crear una aplicación que me permitiera llevar a cabo acciones sobre el IIS para poder realizar acciones tales como crear un Sitio Web desde una aplicación desarrollada en C#. Es por eso, que en este post decidí escribir un poco acerca de como llevar a cabo estas tareas utilizando VS 2008, C#, IIS 7.0 y el API manejado para acceder las funcionalidades del IIS – al menos algunas.

El API de IIS 7.0 es una librería localizada en el directorio C:\Windows\System32\inetsrv\ – Asumiendo que la instalación de Windows esta en el disco C – y es un assemblie que se llama Microsoft.Web.Administration.dll. Esta vez, vamos a hacer una aplicación de consola que nos permita realizar un par de tareas contra el IIS.

Una vez creada la aplicación de consola procedemos a agregar una referencia al componente que nos va a exponer la funcionalidad disponible del IIS, es decir, el Microsoft.Web.Administration.dll. La siguiente figura nos muestra la referencia agregada al proyecto de ejemplo.

image

Una vez agregada esta referencia, procedemos agregar la referencia a la libreria para poder utilizarla en nuestra aplicación tal y como se muestra en el siguiente código:

using System;
using Microsoft.Web.Administration;



Luego a agregar funcionalidad a nuestra aplicacion para acceder al IIS 7.0. Lo primero que vamos a hacer es desplegar la lista de sitios web que han sido creados en el IIS con el que vamos a interactuar, en este caso, el servidor Web local. El código para llevar a cabo este procedimiento es el siguiente.



static void Main( string[] args )
{
ListarSitiosWeb( );
}

private static void ListarSitiosWeb( )
{
using (ServerManager server = new ServerManager( ))
{
foreach (Site site in server.Sites)
{
Console.WriteLine("Sitio Web:{0}", site.Name);
}
}
}



Como se ve en el código anterior, lo primero que debemos hacer es crear una instancia de la clase ServerManager, la cual representa el servidor Web instalado en mi máquina. Seguidamente, para imprimir el nombre de los sitios web creados en el servidor Web simplemente recorro la colección de Sites presente en mi servidor web. La salida de este código es:



image





Para crear un Sitio web desde mi aplicación en .NET utilizo el siguiente código.



/// <summary>
///
Permite crear un web site utilizando el API de IIS 7
/// </summary>
/// <param name="siteName">
El nombre del sitio web</param>
public static void CreateSite( string siteName )
{
try
{
using (ServerManager mgr = new ServerManager( ))
{
Site newSite = mgr.Sites.CreateElement( );
newSite.Id = DateTime.Now.Second;
newSite.SetAttributeValue("name", siteName);
mgr.Sites.Add(newSite);
mgr.CommitChanges( );
}
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.ToString( ));
}
}


Este código permite crear un sitio web con el nombre que viene por parámetro – siteName – y con un Id obtenido del segundo en que fue creado el sitio web. Seguidamente agregamos el sitio a la colección de sitios del IIS, y le damos CommitChanges para refrescar el sitio web.



Otra funcionalidad con la que tenemos que trabajar cuando creamos es crear una Aplicación. Una aplicación en IIS es un agrupamiento de contenido en un sitio Web. Estas aplicaciones tienen una ruta física para el contenido y propiedades que son específicas al contenido indicado. Para crear una aplicación en el sitio web antes creado agregamos el siguiente código.



private static void AgregarAplicacion( string sitioWeb )
{
try
{
using (ServerManager server = new ServerManager( ))
{
server.Sites[sitioWeb].Applications.Add("/", @"C:\Proyectos\MiSitio");
server.CommitChanges( );
}
}
catch (Exception ex)
{
Console.WriteLine("Error creando aplicación {0}: {1}", sitioWeb, ex.ToString( ));
}
}



En este código, el método Add de la colección de aplicaciones del sitio web recibe dos parámetros, el primero es la ruta dentro del servidor web donde se va a administrar el contenido – en este caso en el directorio raíz del sitio web - , y el segundo parámetro que indica la ubicación física del contenido.



Por último, le vamos a agregar un directorio virtual a la aplicación que acabamos de crear.



public static void AgregarDirectorioVirtual( string nombreSitioWeb, string aplicacion )
{
using (ServerManager server = new ServerManager( ))
{
Site sitioWeb = server.Sites[nombreSitioWeb];
Application app = sitioWeb.Applications[aplicacion];
app.VirtualDirectories.Add("/ASPX", @"C:\Proyectos\MiSitio");
server.CommitChanges( );
}
}


Este código agregar un directorio virtual llamado ASPX, en la ruta física C:\Proyectos\MiSitio, por lo tanto va a estar mapeado a esta dirección física.