viernes, 11 de abril de 2008

Proteger contenidos de nuestras webs en html

Yo utilizo 2 métodos uno mas robusto que otro pero los 2 tienen sus resultados.

Método un sencillo

Aunque todo lo que publicamos en Internet puede ser copiado y pegado en otras webs, con gran facilidad, son muchos los que se apuntan a poner algunas dificultades…
Añadiendo el siguiente código en la etiqueta <body> los visitantes a nuestra página no podrán seleccionar el texto ni las imágenes publicadas.
oncontextmenu = “return false” onselectstart = “return false” ondragstart = “return false”
Una medida que no soluciona el problema de la copia indiscriminada de contenidos en la Red, pero que disuadirá a algunos amigos de publicar contenidos ajenos.

Método java script

Pondremos en head éste script, que luego no hará falta cargarlo en body siquiera.

;

martes, 8 de abril de 2008

¿GUID o IDs autonuméricos en bases de datos?

En un post anterior comentaba la idoneidad de un GUID para identificar de forma única e inequívoca elementos como podían ser los registros de una tabla de una base de datos.

Tradicionalmente utilizo claves artificiales, más concretamente autonuméricos, para casi todo. Incluso a veces más de la cuenta, en esas ocasiones en las que
es antinatural no usar claves naturales, valga la rebuscada frase. Sin embargo, la facilidad con la que se manejan estos identificadores, la maximización del rendimiento y espacio ocupado hacen que olvide cualquier otro criterio y me incline hacia esos números consecutivos que automáticamente el sistema genera para nosotros.

Sin embargo, cualquiera que haya usado autonuméricos para diseñar una aplicación medianamente compleja se habrá topado con una serie de inconvenientes como:

  • la imposibilidad para predecir su valor. En otras palabras, hay veces que debemos dividir las sentencias o interfaces de introducción de datos en tablas enlazadas en varios pasos, con objeto de obtener los autonuméricos asignados en algunas de ellas y poder establecerlos en las tablas que vinculan a éstas.
  • no son consecutivos, determinados acontecimientos como la cancelación de una transacción pueden hacer que aparezcan huecos en las asignaciones, lo que puede provocar el efecto pánico de borrado accidental.
  • son problemáticos a la hora de volcar información entre tablas o bases de datos distintas. Por ejemplo, para exportar una serie de tablas relacionadas mediante IDs de una base de datos a otra, suele ser necesario la creación de scripts o incluso aplicaciones relativamente complejas que traduzcan los identificadores de la base de datos origen a los asignados en la de destino, manteniendo las relaciones intactas. Labor de monos, vaya.
  • en el mismo escenario anterior, puede ocurrir que a la hora de realizar fusiones entre tablas un identificador concreto esté ocupado en ambas, lo que hace necesario de nuevo la creación de aplicaciones de volcado.

A estos casos, seguro que habituales, hay que añadir otros escenarios más complejos y menos cotidianos, como los relativos a bases de datos distribuidas, sincronizaciones o replicaciones.

Los GUID pueden solucionar en parte estos problemas, puesto que ofrecen las ventajas de la unicidad, ampliada más allá del alcance de la simple tabla, a la vez que permiten una manipulación más directa por parte del usuario, es decir:

  • los GUID son únicos de verdad, y de forma universal. Vamos, que no se van a repetir (recordemos que existen más de 1038 valores distintos) ni siquiera en tablas distintas, ni en bases de datos diferentes. Ideal para entornos distribuidos, mezclas de datos, volcados, etc.
  • pueden ser generados por aplicaciones, no es necesario esperar a crear un registro para obtener el GUID que será asignado a un registro; podemos generarlo de forma anticipada desde nuestra aplicación y utilizarlo a nuestro antojo.

Pero como casi todo en la vida, esto tiene su precio. Los principales inconvenientes son el mayor consumo de espacio, con la consiguiente merma del rendimiento en consultas y actualizaciones, dispersión de los valores creados (problemático en el uso de clústers o agrupaciones por valores) y, para mi gusto, casi lo peor de todo: la dificultad para depurar (¿quién ve práctico buscar en una tabla diciendo select * from clientes where id={BAE7DF4-DDF-3RG-5TY3E3RF456AS10} en vez de select * from clientes where id=17?).

Deshabilitar/Habilitar un validador ASP.Net desde Javascript

Javascript, ese lenguaje tan de moda, nos permite manipular en cliente algunas propiedades de los utilísimos validadores de ASP.Net.

La función
ValidatorEnable, proporcionada por la plataforma .Net en cliente y utilizable mediante scripting, nos permite habilitar o deshabilitar validadores de nuestros Webforms sin necesidad de hacer un postback. Un ejemplo de uso sería el siguiente:


function onOff(validatorId, activar)
{
var validator =
document.getElementById(validatorId);
ValidatorEnable(validator, activar);
}


El segundo parámetro sería el booleano (true o false) que indica si se desea activar o desactivar el validador. El primer parámetro es el ID en cliente del mismo, y podemos obtenerlo usando la propiedad ClientID del control; por ejemplo, imaginando que tenemos un validador de tipo
RequiredFieldValidator llamado Rfv en nuestro Webform, una llamada a la función anterior sería algo así como:

function algo( )
{
onOff("<%= Rfv.ClientID %>", true);
}

Modificar páginas maestras en tiempo de ejecución en ASP.Net

Hasta hoy pensaba que la página maestra (MasterPage) de un .aspx era una propiedad que se definía en tiempo de diseño, concretamente en las directivas de página, y no era posible modificarlo de forma programática al encontrarse la declaración a un nivel tan bajo:


<%@ Page Language="C#" MasterPageFile="~/Site1.Master"
AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs"
Inherits="PruebasVariadas.WebForm1"
Title="Página sin título" %>


Nada más lejos de la realidad. Aunque con algunas restricciones, es perfectamente posible alterar en tiempo de ejecución la MasterPage de la página, haciendo posible cosas como, por ejemplo, modificar completamente la apariencia y disposición de los elementos sobre la marcha.

Por ejemplo, el siguiente código hace que una página .aspx utilice una maestra u otra en función de si la hora actual del servidor es par:


// C#:
protected override void OnPreInit(EventArgs e)
{
if (DateTime.Now.Hour % 2 == 0)
this.MasterPageFile = "~/Maestra1.master";
else
this.MasterPageFile = "~/Maestra2.master";

base.OnPreInit(e);
}


' VB.NET:
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
If DateTime.Now.Second Mod 2 = 0 Then
Me.MasterPageFile = "~/Maestra1.master"
Else
Me.MasterPageFile = "~/Maestra2.master"
End If
MyBase.OnPreInit(e)
End Sub


Las restricciones a las que me refería antes están plasmadas en esta porción de código: sólo puede cambiarse en el evento PreInit o antes. A efectos prácticos, sobreescribir OnPreInit (como en el ejemplo anterior) es una buena solución.