lunes, 22 de diciembre de 2008

Todo los tipos de conexiones a datos posibles

En este sitio se pueden encontrar todas formas que conectar con diferentes bases de datos.

http://www.connectionstrings.com/

 

martes, 28 de octubre de 2008

Forzar descarga de un archivo

Esto es para forzar la descarga de un pdf puede ser util para imagenes y/o otras cosas que los navegadores por defecto abren.

Colocar en el page_load:

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=mifactura.pdf");
Response.WriteFile(@"C:\Desacarga\test.pdf");
Response.End();

Esto va a hacer que el navegador pregunto donde guardar el archivo que esta en el servidor C:\Desacarga\test.pdf con el nombre mifactura.pdf


Desactivar un Boton mientras se hace el submit

Para evitar que se envíen varias veces la misma información (suele pasar cuando hay un proceso lento en el lado del servidor y un cliente impaciente), es útil desactivar el botón que provoca el postback.

        Button1.Attributes.Add("onclick", "javascript:document.getElementById('"
         + Button1.ClientID + "').disabled=true;" +
         this.GetPostBackEventReference(Button1));

Si es que se llama Button1 el botón que se quiere desactivar. Colocar esa línea dentro del onLoad de la pagina

Error No se pudo cargar viewstate

No se pudo cargar viewstate. El árbol de control en que se está cargando viewstate debe coincidir con el árbol de control que se utilizó para guardar viewstate durante la solicitud anterior. Por ejemplo, al agregar controles de forma dinámica, los controles agregados durante una devolución deben coincidir con el tipo y posición de los controles agregados durante la solicitud inicial.

Se soluciona agregando: EnableViewState=”false” al tag Page de la vista de código de la pagina aspx.

Recuperar el id del ultimo registro insertado

Algo muy comun es querer saber el id del último registro insertado, acá posteo un ejemplo de como hacer eso para una base de datos SQL Server en c#:

SqlConnection conn= new SqlConnection(

ConfigurationManager.ConnectionStrings["dbConn"].ConnectionString

);

string insertStr ="INSERT INTO [tabla]([texto],[fecha]) VALUES(@texto,getDate())

;SELECT Scope_Identity();";

SqlCommand cmd=new SqlCommand(insertStr,conn);

cmd.Parameters.Add("@texto", SqlDbType.NVarChar).Value="El texto va aca";

cmd.Connection.Open();

string ret=cmd.ExecuteScalar().ToString();

cmd.Connection.Close();

La parte clave esta en la sentencia Select Scope_Identity() del sql.

martes, 6 de mayo de 2008

Lo nuevo de Visual Basic .NET

Los tipos de datos.

  • No se admite el tipo Variant, ha sido sustituido por Object. El valor predeterminado de Object es Nothing, en el caso de Variant era Empty.
  • En vb6 el tipo Integer era un número de 16 bits, en vb .net el tipo Short reemplaza a Integer, el Interger pasa a tener 32 bits y el long 64 bits.
  • El tipo de datos Currency se ha convertido en Decimal. Currency tenía 64 bits, con 4 dígitos a la derecha de la coma.
  • Decimal es un número de 96 bits entero y puede constar de hasta 28 dígitos a la derecha de la coma.
  • El tipo Date era un entero doble de 64 bits. En .net es un entero.



Cadenas.

  • Vb .net no admite cadenas de longitud fija.
  • La función DefType que asigna un tipo predeterminado a todas las variables declaradas sin tipo ya no se admite, al igual que DefInt, DefStr, DefBool y DefLng.
  • VarPtr, StrPtr, ObjPtr. Estas funciones que devuelven las direcciones enteras de variables en invocaciones a la API, ya no se admiten. El método AddrOfPinnedHandle de las clase GCHand proporciona una funcionalidad similar.


Matrices.

  • Todas las matrices tienen base 0.
  • Las matrices no pueden ser fijas. No se pueden declarar matrices con tamaño fijo, mediante la especificación de su límite superior e inferior al diseñarlas. Tan solo se puede declarar el límite superior, ya que el inferior es 0.
  • La instrucción Option base no se admite.
  • La instrucción Redim se modifica. No se puede utilizar en la declaración de una variable de matriz.



Varios.

  • El valor de True es -1, este no ha cambiando en .net, sin embargo en el motor CLR, True equivale a 1.
  • Vb .net no admite los tipos de datos definidos por el usuario. Han sido sustituidos por estructuras. Constan de estructuras similares pero son mucho más potentes.
  • La funcion MsgBox ha sido sustituida por el método Show de la clase MessageBox.
  • Propiedades predeterminadas. Vb .net ya no admite las propiedades predeterminadas para cualquier objeto.



Operadores.

  • El operador EQV se ha sustituido por el operador “=”.
  • Se han añadido los operadores AndAlso y OrElse para procesar los cortocircuitos.
  • Nuevos operadores de asignación.
    +=, -=, *=, /=, \=, ^=, &=



Variables.

  • Ámbito: las variables se pueden declarar dentro de bloques de instrucciones, en cuyo caso sólo estarán disponibles en su interior.
  • Declaración: las variables se pueden definir en la misma línea en la que se declaran. También se pueden declarar múltiples variables en la misma línea.


Procedimientos.

  • Invocación de procedimientos: ya se trate de subprocedimientos o funciones requiere el uso de paréntesis para incluir argumentos, aunque no se incluya ninguno.
  • Procedimientos estáticos: estos ya no se admiten. Se deben definir las variables dentro del procedimiento como Static.
  • ByVal, ByRef, As Any: en vb6 el mecanismo predeterminado para transferir parámetros es ByRef. En vb .net es ByVal. Ya no se admite la instrucción As Any de la instrucción Declare para invocaciones API.



Flujo de control.

  • La instrucción While … WEnd ya no se admite.
  • La bifurcación GoSub a otra subrutina dentro de una procedimiento ya no se admite.
  • En vb .net la instrucción Return devuelve el control a la instancia que invoque la función. Si la función es de un determinado tipo, puede devolver también el valor.


Formularios.

  • El método PrintForm ha dejado de ser válido. El entorno .net framework dispone de un nuevo subsistema de impresión, en el que se incluye una función de visualización previa.
  • Circle, Cls, PSet, Line y Point ya no se admiten en vb .net. los métodos gráficos de vb6 se han sustituido por el espacio de nombre System.Drawing, el cual utiliza las nuevas clases GDI+ para dibujar.
  • La propiedad Caption de los controles etiqueta y formularios ya no se admite. La propiedad Text ha pasado a sustituirla.
  • La unidad de medida Twips utilizada en formularios ha sido sustituida por Píxeles.
  • Fuentes: los formularios en vb6 se podían crear utilizando cualquier tipo de fuente admitida por Windows. Ahora solo se admiten fuentes True Type o Open Type.
  • Matrices de controles: en vb .net los controles no se pueden agrupar en matrices, pero se puede utilizar el mismo procedimiento para utilizar controles múltiples con la palabra clave Handles.
  • Menús contextuales y menús principales: en un formulario vb6 se puede tener un menú principal y un menú contextual.
  • En vb .net solo se puede tener uno de los dos.


Controles.

  • El control OLE ya no se admite.
  • El control Image se ha sustituido por el PictureBox.
  • El control Line ha sido sustituido por los métodos GDI+ Draw.
  • El control Shape ha sido sustituido por los métodos GDI+ Draw.



Tipos de aplicaciones.

  • Las aplicaciones Clases de Web, Documentos Active X, aplicaciones DHTML y las Propiedades de página ya no se admiten.
  • Los controles de usuario creados en vb6 se pueden utilizar en vb .net, pero no existe un entorno de diseño para la edición y modificación de controles.



Acceso a datos.

  • Vb .net no admite el estándar para el acceso a datos DAO. A partit de ahora se utilizará ADO .NET.

Concepto de variable

Es una porción de memoria a la que asignamos un nombre e indicamos qué tipo de información vamos a almacenar en ella (textos, números, fechas, etc).

Hay tres componentes que definen una variable:


1. El nombre de la variable (que se corresponde con su ubicación en la memoria).
2. El tipo de información que está almacenando.
3. La información como tal.



Una Instrucción de asignación sirve para almacenar información en una variable:


Dim Variable As String ‘instanciar la variable
Variable = Valor de cadena ‘asignar la variable a un valor

Dim Variable As String = Valor de cadena ‘instanciar y asignar en la misma línea



En VB .NET incluso los tipos de datos más básicos se comportan como objetos, con sus propiedades y métodos propios.


1. Tipos de Variables.

El entorno .NET Framework se guía por los tipos de datos compatibles con la especificación CLS (Comon Language Specification).

Tipo de VB Tipo CLS Bytes


Boolean System.Boolean 2
Byte System.Byte 1
Char System.Char 2
Date System.DateTime 8
Decimal System.Decimal 16
Double System.Double 8
Integer System.Int32 4
Long System.Int64 8
Object(variant) System.Object 4
Short System.Int16 2
Single System.Single 4
String System.String En función de la plataforma de implementación.
Tipo de datos definido por (hereda System.ValueType) En función de la plataforma de implementación.
el usuario (estructura)





2. Declaración de Variables.

Proceso mediante el cual reservamos espacio en memoria e indicamos el tipo de información que se almacenará.


Dim nombre_variable As tipo

Dim = Dimensión / Dimensionar = Declarar / ReDim = Redimensionar

Dim nombre_variable As Tipo = Valor ‘forma de inicializar una variable



Al declarar más de una variable con la misma instrucción Dim, ya no es necesario indicar el tipo de cada una de ellas.
El ámbito de la variable determina la posibilidad de acceder a ella en determinadas secciones de la aplicación.
Si la variable es declarada con Dim dentro de una función, solo será visible desde su interior y su vida se limita a la ejecución de dicha función.
Si la variable es declarada dentro de un bucle o una condicional, solo será accesible desde las instrucciones que hay dentro de ese bloque.
Si la variable se declara a nivel de módulo o clase, será compartida por todo el código de esta entidad.
La instrucción Option Explicit, obliga a declarar las variables antes de poder hacer referencia a ellas. Se puede indicar en las propiedades del proyecto que asuma esta instrucción por defecto.

Aunque se tenga total libertad a la hora de colocar nombres de variables, es conveniente seguir una convención de nombres respecto a las variables:

1. El nombre debe empezar por una letra y no por un número u otro carácter.
2. El resto del nombre puede contener letras, números y/o caracteres subrayados. No se permite que haya espacios, puntos u otros signos de puntuación.
3. El nombre deberá ser único dentro del alcance de la variable.
4. El nombre no puede ser una de las palabras reservadas de Visual Basic.


3. Constantes.

Una constante permite asignar un nombre familiar como valor de una variable que no se modificará durante la ejecución de la aplicación. Las constantes funcionaran de la misma forma que lo hacían en las versiones anteriores de este lenguaje. Para declarar una constante, su utiliza la palabra reservada Const.


Const nombre_constante As tipo = valor




4. Ámbito de las Variables.

Private. (a nivel de bloque dentro de una estructura de una procedimeinto) o (a nivel de procedimiento)

Están disponibles en el módulo, clase o estructura en la que se haya declarado. Dim y Private actúan de la misma forma, con la excepción de que la palabra clave Private no se puede utilizar dentro de un subprocedimiento o función.

Public. (a nivel de módulo) o (a nivel de clase)

Está a disposición de todo el namespace (aplicación).

Static. (a nivel de procedimiento)

Una variable estática conserva su valor hasta que se le asigna uno nuevo o hasta la conclusión de la aplicación. Solo se pueden declarar a nivel de procedimiento.

Shared.

Si una variable se declara con la palabra clave Shared, es una variable compartida, y existe en una única copia compartida por todas las instancias de la clase o estructura. Es decir, si cambias el valor de una, cambian automáticamente todas las demás.

Protected. (a nivel de clase)

Las variables protegidas sólo están disponibles para la clase en la que se han declarado o en aquellas que derivan de la misma clase. Solo se pueden declarar a nivel de clase (formulario).

Friend. (a nivel de proyecto)

La palabra clave Friend de la instrucción Dim declara elementos como accesibles desde dentro del mismo proyecto (varias soluciones), pero no desde fuera de él. Solo se pueden declarar a nivel de módulo.


5. Prefijos utilizados en una convención de nombres de variables.

Prefijo Tipo de variable


Str String
Int Integer
Lng Long Integer
Sng Single (Coma flotante de precisión simple)
Dbl Double (Coma flotante de precisión doble)
Dec Decimal (se suele usar para datos moneda)
Bln Boolean
Var Variant
Byt Byte
Col Collection Object
Cur Currency
Dtm Date(Time)
Err Error
Obj Object
Udt User defined type

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.