Curso de ASP.NET MVC 3

10. March 2011 18:45 by Oscar.SS in Formación, Personal  //  Tags: , ,   //   Comments (4)

Normalmente cuando realizo un curso de formación no tengo por constumbre comentar nada al respecto en este blog (no así con los libros),  pero en este caso voy hacer una leve excepción porque la ocasión realmente lo merece.

Recientemente he terminado el temario completo del curso "Desarrollo Web con ASP.NET MVC 3" de la buena gente de Campus MVP. Sinceramente puedo decir que es el curso con el que más he disfrutado de todos lo que he realizado nunca. Aunque a más de uno, los vocablos disfutar y formación les cuestes imaginarlo en la misma frase.

 

 

Para los que venimos de los automatismos que nos brinda ASP.NET Web Forms, adentrarse en las maravillas del patrón MVC puede resultar chocante en primera instancia. Se puede pensar, no sin razón, que existe cierto aumento en la curva de aprendizaje. Esto, que podría resultar un problema a la hora de lanzarse a por esta tecnología, o esta forma de trabajar, lo han resuelto satisfactoriamente con la estructura de los contenidos del curso. Poco a poco (algo más lento para los torpes como yo), y con una acertada organización de los conceptos, te adentras en las maravillas del patrón MVC y de la última versión del framework ASP.NET MVC.

Quizás otra de las preguntas que nos hacemos, y posiblemente la más importante y dificil de solventar al principio, es si un curso merece la inversión económica que vamos a realizar. Es decir, ¿es realmente lo que necesito para mis objetivos?. Esta es una pregunta muy subjetiva que evidentemente su respuesta esta sujeta a los objetivos particulares de cada uno. Pero os puedo asegurar, que si vuesto objetivo es tener los conocimientos y herramientas necesarias para desarrollar aplicaciones profesionalmente con esta tecnología, el curso cumple con esto y mucho más. Realmente os diferenciaréis profesionalmente del resto de vuestros compañeros de trabajo.

Sin duda alguna otra de las ventajas que tiene este curso es su tutor. José María Aguilar es un aténtico crack. Si realizáis este curso, o cualquier otro donde sea, os recomiendo siempre que preguntéis y preguntéis hasta  hartaros. Claro que para preguntar hay que profundizar primero. No cabe duda, que tener un tutor con el nivel de José María, es un valor añadido a la formación, pero solo si lo utilizáis. ¡Así que a preguntar que para eso están!

Seguridad de directorios en ASP.NET

6. March 2011 08:43 by Oscar.SS in Desarrollo Web  //  Tags: ,   //   Comments (10)

Practicamente en la totalidad de nuestras aplicaciones web debemos implementar la seguridad de usuarios para determininar cuales de estos tienen permisos a determinados recursos. Cuando la seguridad sea muy complicada, con multitud de niveles y sobre multitud de recursos, recuriremos a la seguridad basada en perfiles o roles almacenados en una base de datos.

Sin embargo, para contextos de seguridad mucho más simples, podemos usar la seguridad basada en establecer ciertos directorios o elementos como privados y definir unos pocos permisos en el web.config. Por ejemplo, un blog como este, en el que todas las páginas son públicas a todos los usuarios, excepto las encargadas de administrar y editar los artículos que solo serán accesibles al administrador del blog.

En casos tan sencillos como este, basaremos la seguridad mediante formularios, directorios (o elementos) privados, y la definición de permisos de usuarios en el web.config.

Supongamos que estamos desarrollando una aplicación web en el que todas sus páginas serán públicas. El contenido de estas páginas es dinámico y se edita por medio de un back office al que solo podrán acceder los administradores del sitio web. Veamos como hacerlo.

 

Definir directorios privados

En primer lugar, definimos en el web.config que directorios o elementos serán privados y cuales serán públicos. Cuando hablamos de directorios, nos referimos naturalmente a una carpeta (y todo su contenido) de nuestro proyecto. Y cuando hablamos de elementos, nos referimos por ejemplo, a ciertas páginas.

 

 

Mediante la sección <location> del web.config establecemos el directorio BackOffice como privado a todos los usuarios no autentificados.

 

<configuration>
    
<system.web>
        
<!--...-->
    
</system.web>
    
<!--Marcamos el directorio BackOffice como privado-->
    
<location path="BackOffice">
        
<system.web>
            
<authorization>
                
<deny users="?"/>
            
</authorization>
        
</system.web>
    
</location>
    
<!--...............................................-->
</configuration> 

 

Sobre la sección <location> debemos tener hacer varios apuntes:

1- Esta sección se encuentra fuera del elemento <system.web> aunque en su interior tiene una sección hija con el mismo nombre.

2- Podemos tener tantas secciones <location> como necesitemos.

3- El atributo path="" de nuestro ejemplo apunta a un directorio, pero perfectamente prodía apuntar a una sola página path="BackOffice/AdmNoticias.aspx".

4- Mediante la sección <deny users="?" /> denagamos el acceso a todos los usuarios anónimos, es decir, no autentificados. Pero también existe otra posibilidad <allow users="*" /> que da acceso a todos los usuarios ya estén autentificados o no. Con la combinación de ambos elementos estableceremos la privacidad o publicidad de nuestros recursos.

 

Autentificacion mediante formularios

Una vez establecidos, en nuestro sitio web, que recursos serán públicos y cuales privados, definimos en el web.config que la autentificación se realizará mediante formulario.

 

<configuration>
    
<system.web>
        
<!--Establecemos la configuracion de atentificacion-->
        
<authentication mode="Forms">
            
<forms loginUrl="Login.aspx">
                
<credentials passwordFormat="SHA1">
                    
<user name="administrador1" password="C46D4FJ43L6KJ424355403CCE60B85421E5E6FB62"/>
                    <
user name="administrador2" password="56J35K6J353KLL56P635KJ33L6KJ424356980MRMG"/>
                </
credentials>
            
</forms>
        
</authentication>
        
<!--...............................................-->
    
</system.web>
</configuration> 

 

En primer lugar definimos el atributo mode="Forms" indicando que la autentificación se realizará mediante formulario. En el atributo loginUrl="" indicamos la ruta en nuestro proyecto donde se encontrará el formulario de login donde los usuarios tendrán que autentificarse. Será ASP.NET quién se encarge de redirigir automaticamente a los usuarios a este formulario cuando se intente un acceso a un recurso protegido.

 

 

Mediante la sección de credenciales definimos que estás estarán codificadas mediante el algoritmo SHA1. Tan solo es una forma de proteger las contraseñas de los usuarios para que no estén estricas literalmente en el web.config o para evitar su visibilidad si la solicitud es "leida" por usuarios maliciosos.

A continuación mediante la sección <user> definimos las credenciales de los usuarios (nombre y contraseña) que tendrán acceso a los recursos privados. Ahora veremos como generar estos valores hash de codificación.

 

Generar valores hash

Para generar los valores hash de las contraseñas hacemos lo siguiente.

string claveHash System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile("contraseñaUsuario""SHA1");

Al ejecutar este código, el valor de la variable claveHash contendrá la codificación SHA1 de la contraseña del usuario. Solo tendremos que copiarla y pegarla en la sección correspondiente del web.config. Naturalmente este proceso de copiar y pegar a mano en el web.config las contraseñas codificadas es poco ortodoxo, pero como ya comentamos anteriormente, estamos hablando de un contexto de seguridad donde tenemos muy pocos usuarios con credenciales. Si tuvieramos 100 usuarios con distintos roles, sería inmantenible realizarlo por este sistema en lugar de almacenarlos en una base de datos.

 

Validación de usuarios

Cuando los usuarios introducen en el formulario anterior sus credenciales (nombre y contraseña)...¿como los validamos contra las credenciales definidas en el web.config?

 

    protected void ibLogin_Click(object sender, System.Web.UI.ImageClickEventArgs e)
    {
        
if (System.Web.Security.FormsAuthentication.Authenticate(txUsuario.Value, txPassword.Value))
            System.Web.Security.FormsAuthentication.RedirectFromLoginPage(txUsuario.Value, 
false);
        else
            
spError.InnerText "Usted no está autorizado para entrar a este sitio";
    
}

 

En primer lugar, comprobamos si las credenciales escritas en el formulario por el usuario corresponden con algunas de las que hemos defnimos anteriormente en el web.config. En caso afirmativo, redirigimos al usuario al recurso al que estaba intentando acceder.

De esta redirección se ocupa por nosotros ASP.NET. Funciona de la siguiente manera. Cuando nosotros intentamos acceder a un recurso protegido mediante una petición,

- GET //www.misitio.com/BackOffice/AdmNoticias.aspx

ASP.NET nos redirige automaticamente al recurso que hemos establecido como login en el web.config de la siguiente forma.

- GET //www.misitio.com/Login.aspx?ReturnUrl=/BackOffice/AdmNoticias.aspx

Como se puede apreciar en la url anterior, ASP.NET se encargará, mediante el parámetro de QueryString ReturnUrl una vez verificadas las credenciales del usuario, de enviarnos al recurso al que intentabamos acceder.

Detener un PostBack con JavaScript

5. February 2011 21:00 by Oscar.SS in Desarrollo Web  //  Tags: ,   //   Comments (1)

En ocasiones nos interesará detener una petición al servidor desde el cliente. Por ejemplo, cuando el usuario elimina un registro desde la interfaz de pantalla y antes de realizar la llamada al servidor, le preguntamos con un alert() si está seguro de que quiere eliminar el registro. O también, cuando validamos algún tipo de dato y en caso de no pasar la validación evitaremos el código de servidor.

Esta funcionalidad se puede implementar de varias formas diferentes, aquí veremos una de ellas. Supongamos la siguiente interfaz de usuario.

 

Es muy simple, el usuario escribe su nombre y pulsa el botón para recebir un saludo, pero antes le preguntamos si desea recibirlo.

 

 

En primer lugar vamos a ver el código HTML de nuestra interfaz que tiene algunos detalles muy interesantes.

 

    <div>
        Nombre: 
<input type="text" id="txNombre" runat="server" />
        <
input type="button" value="Saludar" id="btSaludar" onclick="javascript:if(quiereUnSaludo())" runat="server" />
        <
br />
        <
br />
        <
span id="spSaludo" runat="server"> </span>
    
</div> 

 

En lo primero que tenemos que fijarnos es que hemos utilizado un botón HTML de tipo "button" y no de tipo "submit". Esto debe ser así, porque de lo contrario siempre iríamos a servidor independientemente de lo que implementemos en JavaScript.

Es evidente que tenemos que marcar el botón para que corrar del lado del servidor (runat="server") dado que queremos ir al servidor dependiendo de la validación de JavaScript.

Y en lo último que debemos fijarnos es que en el evento onclick tenemos una condición llamando a una función personalizada que devuelve un boleano. Esta función de JavaScript es donde implementaremos, por ejemplo, que se han validado ciertos datos, o que el usuario rechaza o acepta la operación que eligió anteriormente. El código de esta función podría ser algo como lo siguiente.

 

    <script type="text/javascript">
        
function quiereUnSaludo() {
            
var response = confirm("¿Desea revibir un saludo?");
            return 
response;
        
}
    </script>

 

Y con esto, recibiremos un true o false en función de lo que elija el usuario. El botón al recibir un false no seguirá ejecutando sus funciones y por lo tanto no irá al servidor. Pero aún nos falta una tarea, ¿cómo enlazamos el botón con el evento de servidor?.

 

    protected void Page_Load(object sender, EventArgs e)
    {
        btSaludar.ServerClick +
= new EventHandler(btSaludar_ServerClick);
    
}

    
protected void btSaludar_ServerClick(object sender, EventArgs e)
    {
        spSaludo.InnerText 
"Hola, " + txNombre.Value + " a las " + DateTime.Now.ToShortTimeString();
    
}

 

Existen otras formas de hacer esto mismo, como por ejemplo, controlando directamente la llamada al método doPostBack() que escribe por nosotros el Framework, pero en mi opinión son menos "limpias" que la aquí expuesta.

Envío de correo en .NET con C#

22. January 2011 14:50 by Oscar.SS in Desarrollo .NET  //  Tags:   //   Comments (12)

El Framework de .NET nos permite enviar correo electrónico desde nuestro código de forma muy sencilla. Conceptualmente se puede resumir en 3 sencillos pasos:

1- Crear el mensaje de correo.

2- Configurar el cliente de correo desde el que enviamos el mensaje.

3- Enviar el mensaje.

 

Para realizar estas operaciones necesitaremos 3 objetos o clases integradas en el Framework:

- System.Net.Mail.MailMessege -> Nos permite encapsular todos las propiedades de nuestro mensaje.

System.Net.Mail.MailAddress -> Representa una dirección de correo electrónico.

- System.Net.Mail.SmtpClient ->Representa un cliente de correo electrónico basado en el protocolo SMTP.

 

Veamos un ejemplo de código:

 

    public void EnviarCorreo()
    {
        
/*-------------------------MENSAJE DE CORREO----------------------*/

        //Creamos un nuevo Objeto de mensaje
        
System.Net.Mail.MailMessage mmsg = new System.Net.Mail.MailMessage();

        
//Direccion de correo electronico a la que queremos enviar el mensaje
        
mmsg.To.Add("destinatario@servidordominio.com");

        
//Nota: La propiedad To es una colección que permite enviar el mensaje a más de un destinatario

        //Asunto
        
mmsg.Subject "Asunto del correo";
        
mmsg.SubjectEncoding System.Text.Encoding.UTF8;

        
//Direccion de correo electronico que queremos que reciba una copia del mensaje
        
mmsg.Bcc.Add("destinatariocopia@servidordominio.com")//Opcional

        //Cuerpo del Mensaje
        
mmsg.Body "Texto del contenio del mensaje de correo";
        
mmsg.BodyEncoding System.Text.Encoding.UTF8;
        
mmsg.IsBodyHtml = false; //Si no queremos que se envíe como HTML

        //Correo electronico desde la que enviamos el mensaje
        
mmsg.From = new System.Net.Mail.MailAddress("micuenta@servidordominio.com");


        
/*-------------------------CLIENTE DE CORREO----------------------*/

        //Creamos un objeto de cliente de correo
        
System.Net.Mail.SmtpClient cliente = new System.Net.Mail.SmtpClient();

        
//Hay que crear las credenciales del correo emisor
        
cliente.Credentials =
            new 
System.Net.NetworkCredential("micuenta@servidordominio.com""micontraseña");

        
//Lo siguiente es obligatorio si enviamos el mensaje desde Gmail
        /*
        cliente.Port = 587;
        cliente.EnableSsl = true;
        */

        
cliente.Host "mail.servidordominio.com"//Para Gmail "smtp.gmail.com";


        /*-------------------------ENVIO DE CORREO----------------------*/

        
try
        
{
            
//Enviamos el mensaje      
            
cliente.Send(mmsg);
        
}
        
catch (System.Net.Mail.SmtpException ex)
        {
            
//Aquí gestionamos los errores al intentar enviar el correo
        
}
    }

Construir un menú Web con Master Page y JQuery

20. December 2010 21:07 by Oscar.SS in Desarrollo Web  //  Tags: , ,   //   Comments (0)

En las aplicaciones Web es habitual tener un menú principal, normalmente horizontal, en la cabecera de la página. Este menú presenta a los usuarios el contenido principal de la Web permitiendoles navegar con facilidad por la misma. Por ejemplo un menú como el siguiente:

 

 

Este menú consta de 5 imágenes, una por cada botón que puede pulsar el usuario.

Voy a resumir en pocos pasos la funcionalidad que deberá tener este menú.

1- Cuando los usuarios pasen el ratón por encima de los distintos botones del menú, aparecera una pequeña marca, o cambiará de color el botón, o cualquier otro efecto que se os ocurra, para informar al usuario de que esta zona de la página "tiene vida".

 

 

En este caso, esta pequeña marca la conseguimos con otra imágen del botón, que contiene este efecto. Es decir, que tendremos 5 imágenes para los botones sin pulsar y 5 imágenes para los botones pulsados.

2- Cuando el usuario esté en una página concreta, el botón del menú relacionado con esta página deberá quedar marcado con el efecto que diseñamos en el paso anterior. Así los usuarios siempre tendrán la certeza de que página están visitando. Estos pequeños detalles de diseño centrado en el usuario son más importantes de lo que parecen.

Naturalmente si tenemos una web con varias páginas de contenido, lo más recomendable es que utilicemos una Master Page. El código HTML de nuestro menú lo incluiremos en la Master Page y al referenciar el resto de páginas a esta, no tendremos que repetir el mismo código en todas la páginas.

 

Paso 2. Marcar el botón al entrar al contenido de una página.

Dado que el menú se encuentra en la Master Page tendremos que acceder a ella desde las páginas de contenido. Para ellos pondremos un código como el siguiente en el evento Load de las páginas de contenido.

    protected void Page_Load(object sender, EventArgs e)
    {
        var img 
(System.Web.UI.HtmlControls.HtmlImage)this.Master.FindControl("imgInstalaciones");
        
img.Src "img/home/instalaciones_on.jpg";
    
}

Os recomiendo que leais este artículo para entender mejor el código anterior. Fijaros que el nombre de la imágen tiene un sufijo _on. Ahora mismo veremos porque.

 

Paso 1. Efecto onMouseOver y onMouseOut.

Con JQuery implementamos la funcionalidad para que los botones cambien la imágen, o cualquier otro efecto, al pasar el ratón por encima.

$(document).ready(function () {
    $(
'.menu img').hover(
        
function () {
            
var src $(this).attr('src').replace('_off''_on');
            
$(this).attr('src', src);
        
},
        
function () {
            
var src $(this).attr('src').replace('_on''_off');
            if 
(permitirReplaceOnOff(src)) {
                $(
this).attr('src', src);
            
}
        })
;
});

La función hover() de JQuery toma dos parámetros como funciones, que representan respectivamente el evento onMouseOver y onMouseOut. Lo que hacemos en cada caso, para intercambiar entre el botón activo y el botón inactivo, es reemplazar en el atributo src de la imágen el sufijo _on por el sufijo _off.

Fijaros que en la segunda función (evento onMouseOut), tenemos una condición para evitar que se produzca el cambio de la imágen. ¿Por qué hacemos esto?.

Una vez que el usuario pulsa un botón, desde el evento Load de servidor establecemos la imágen que representa el botón activo. Pero después de pulsar, el usuario moverá el ratón y saldrá del botón disparando el evento de cliente onMouseOut y revirtiendo el cambio que hemos realizado desde el servidor.

function permitirReplaceOnOff(src) {
    var permitir 
= true;
    
var urlActual window.location.pathname;

    if 
(src.indexOf('casos_exito') !-&& urlActual.indexOf('CasosExito') !-1) {
        permitir 
= false;
    
}

    
if (src.indexOf('contacto') !-&& urlActual.indexOf('Contacto') !-1) {
        permitir 
= false;
    
}

    
if (src.indexOf('horarios') !-&& urlActual.indexOf('Horarios') !-1) {
        permitir 
= false;
    
}

    
if (src.indexOf('instalaciones') !-&& urlActual.indexOf('Instalaciones') !-1) {
        permitir 
= false;
    
}

    
if (src.indexOf('servicios') !-&& urlActual.indexOf('Servicios') !-1) {
        permitir 
= false;
    
}

    
return permitir;
}

Lo que hacemos es comparar respectivamente cada imágen del menú con cada página de contenido. Y cuando coincidan, no dejar que se dispare el evento onMouseOut. Esta solución es un poco pobre pero...funciona. Se admiten sugerencias  ;-)

Recent Comments

Comment RSS

Month List