Como rescatar de las llamas del infierno un MDF sin el LDF

agosto 11, 2009 07:27 by sergio

Tomando como referencia el tipo de redacción de mi colega DDAZ voy a escribir este POST haciendo alusión a un “posible” caso de la vida real. Quiero aclarar que no soy DBA y no soy una eminencia optimizando sentencias SQL o una cosa por el estilo. Los nombres utilizados y su parecido con la realidad son mera coincidencia. 

El DBA despistado 

Josué, el encargado de la integridad de la información  y de los aspectos ambientales de la información de de una prestigiada empresa prestadora de servicios de tecnología (DBA), consiente y preocupado ante cualquier proceso de recuperación de desastres, análisis de rendimiento y optimización de base datos, olvidó (“por error”). Programar ya sea incrementalmente, diferencialmente o totalmente respaldos propios de la información contenida en las bases de datos de la compañía. 

Un día (viernes, que raro), ocurrió algo que estaba contenido en el plan de recuperación a desastres y solo se pensaba que podría llegar a ocurrir si el experimento que se está realizando en Suiza (entre las montañas del Jura y el lago de Ginebra), generara un poderoso arranque de gravedad que comprimiera la materia y terminara con la vida tal cual la conocemos. Un simple apagón de energía eléctrica, lo cual ocasionó que se dañaran varios sectores en disco duro, se malogrará el sistema de arranque del sistema operativo y se perdieran los log de transacciones de todas las bases de datos (LDF).

Cabe mencionar que el SMBD era SQL Server. La empresa sufrió mucho operativamente y la información vital de la misma, jamás se pudo recuperar. JAMÁS!! 

¿Por qué Sucedió esto? 

Josué, como todo profesionista promedio, tuvo un escenario en donde la teoría no sirve para nada ante situaciones prácticas donde se requiere actuar rápido para mantener el negocio. Adicionalmente también desconocía las bondades y la importancia de realizar respaldos de sus bases de datos como lo detalla la siguiente tabla*: 

 

Respaldo

Archivos en Respaldo Ventajas Desventajas
Completo ("Full") Todos Con este respaldo únicamente es posible recuperar toda la información Tiempo de Ejecución
De Incremento ("Incremental") Archivos con archive bit activo.(Aquellos que hayan cambiado desde el último Respaldo Completo) Velocidad Requiere del último Respaldo Completo y de todos los Respaldos de Incremento que le siguieron para recuperar el Sistema
Diferencial ("Differential") Archivos con archive bit activo.(Aquellos que hayan cambiado desde el último Respaldo Completo) Sólo requiere del último Respaldo Completo y del último respaldo Diferencial Ocupa mayor espacio en discos comparado con Respaldos de Incremento

*Clasificación de Respaldos. Osmosis Latina - http://www.osmosislatina.com/soporte/respaldos.htm 

¿Qué hacer si ya valió? 

Cabe mencionar que la siguiente alternativa solo funciona para SQL Server y no es una opción muy “elegante” al problema, yo sigo la siguiente filosofía: “A problemas piñatas, soluciones piñatas”, no por algo tengo un diploma a las “marranadas” (hablando de soluciones tecnológicas). 

La solución propuesta sería: 

1.    Crear las bases de datos afectadas en blanco, detener el servicio de SQL Server y cambiar el MDF por el que rescataron del server caído (Q.E.P.D). 

2.    Eliminar el LDF que se generó en blanco y reiniciar el servicio de SQL. Dado esto debería marcar la base de datos como suspect. 

3.    Posicionarse en la base de datos MASTER (USE MASTER) 

4.    Cambiar las opciones de configuración global del servidor actual para que permita hacer cambios al mismo. 

EXEC sp_Configure 'ALLOW UPDATES', 1
RECONFIGURE WITH OVERRIDE 

5.    Cambiar el estado de la base de datos a MODO DE EMERGENCIA. 

UPDATE SYSDATABASES SET STATUS = 32768 WHERE NAME = 'NombreBaseDeDatos'  

6.    Cambiar las opciones de configuración global del servidor actual para que ya no permita hacer cambios al mismo

EXEC sp_Configure 'ALLOW UPDATES', 0
RECONFIGURE WITH OVERRIDE 

7.    Cambiar la base de datos afectada a opción de usuario simple. 

EXEC sp_DBOption 'ArchivoIntegracion', 'SINGLE USER', 'TRUE' 

8.    Reconstruir el LOG de transacciones (LDF) de la base de datos (MDF). 

DBCC REBUILD_LOG ('NombreBaseDeDatos', 'C:\Program Files\Microsoft SQL Server\MSSQL\Data\NombreBaseDeDatos_Log.ldf') 

9.    Cambiar las opciones de configuración global del servidor actual para que permita hacer cambios al mismo. 

EXEC sp_Configure 'ALLOW UPDATES', 1
RECONFIGURE WITH OVERRIDE 

10. Cambiar el estado de la base de datos a MODO NORMAL. 

UPDATE SYSDATABASES SET STATUS = 0 WHERE NAME = 'NombreBaseDeDatos' 

11. Cambiar las opciones de configuración global del servidor actual para que ya no permita hacer cambios al mismo 

EXEC sp_Configure 'ALLOW UPDATES', 0
RECONFIGURE WITH OVERRIDE 

12. Cambiar la base de datos afectada a opción de usuarios múltiples. 

EXEC sp_dboption 'ArchivoIntegracion', 'SINGLE USER', 'FALSE' 


Y voila, ya quedó milagrosamente rescatado nuestro MDF sin necesidad de contar con el LDF respectivo. Josué ya puede estar más tranquilo al respecto y tener más cuidado para la próxima vez que ocurra esto en su organización (que esperemos y jamás vuelva a suceder).


Actualmente calificado con 5.0 por 3 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Clases Abstractas vs Interfaces. ¿Cómo, Cuándo y Por Qué?

febrero 17, 2009 07:10 by sergio

Enviado por Johnatan Flores Carmona el 17 de febrero de 2009  

Saludos a todos, en esta nueva aportación quiero compartir con ustedes un tema que cuando se está iniciando en el aprendizaje de la programación orientada a objetos no se encuentra en ningún libro o bien, pocos instructores lo mencionan -debo admitir que cuando impartí la materia de Introducción a la Programación Orientada a Objetos en el Instituto Tecnológico de León ni siquiera lo mencioné- y me refiero a ¿Cuándo y por qué usar clases abstractas o interfaces?

El concepto de clases abstractas e interfaces puede ser un poco confuso para los principiantes en la programación orientada a objetos ya que una clase abstracta sin ninguna implementación se ve cómo una interface, sin embargo existen muchas diferencias y similitudes entre ellas.

¿Qué es una clase abstracta?

Una clase abstracta es una clase que no puede ser instanciada y que debe ser heredada. Una clase puede implementarse en su totalidad, pero lo más habitual es que se implemente parcialmente o no se implemente en absoluto, encapsulando funcionalidad común para clases heredadas. Para información más detallada, vea Clases abstractas.

¿Qué es una Interface?

Una interface describe un grupo de comportamientos relacionados que pueden pertenecer a cualquier clase o estructura. Las interfaces contienen las firmas de métodos, propiedades, eventos o indizadores. La implementación de los miembros se hace en la clase o la estructura que implementa la interfaz. Para información más detallada, vea Interfaces.

Diferencias y Similitudes

A continuación extraigo parte de una tabla del artículo Abstract Class versus Interface en la que se describen las diferencias y similitudes que existen entre las clases abstractas y las interfaces:

Característica

Interface

Clase abstracta

Herencia Múltiple

Una clase puede heredar tantas interfaces requiera.

Una clase sólo puede heredar una clase abstracta.

Implementación por defecto

Una interface no puede proporcionar ningún código de implementación, solo la firma.

Una clase abstracta puede proporcionar la implementación completa o parcial.

Modificadores de acceso

Una interface no puede tener modificadores de acceso, todas sus firmas son públicas.

Los miembros de una clase abstracta pueden tener modificadores de acceso.

Núcleo vs Periferia

Las interfaces son usadas para definir las habilidades periféricas de una clase. Un Humano y un Vehiculo pueden implementar una interface IMovible

Una clase abstracta define el núcleo de una clase y es usada para objetos del mismo tipo.

Campos y Constantes

No pueden ser definidas en una interface

Una clase abstracta puede contener campos y constantes.

Recomendaciones para el uso de clases abstractas vs interfaces

La opción de diseñar tu funcionalidad cómo una interface o cómo clase abstracta puede ser difícil en algunas ocasiones. Microsoft en su artículo Recommendations for Abstract Classes vs. Interfaces nos hace las siguientes recomendaciones que trataré de ejemplificar para mostrar las ventajas de seguirlas.

Múltiples Versiones

Si sabe de antemano que va a crear varias versiones del componente, cree una clase abstracta. Las clases abstractas proporcionan un medio fácil y sencillo para crear versiones de los componentes. Al actualiza la clase base, todas las clases heredadas se actualizan automáticamente con el cambio. Por el contrario, las interfaces no se pueden cambiar una vez creadas. Si necesita una nueva versión de una interfaz, deberá crear una totalmente nueva.

Ejemplo: Pensemos en el caso de crear el ABC de una base de datos que contiene la tabla Persona, y además dos especializaciones de esta llamadas Cliente y Empleado; también existe la regla de negocio que indica que no puede registrarse a una persona si no es registrada cómo cliente o cómo empleado.

Solución con Clases Abstractas: Se debería de crear una clase abstracta llamada Persona y que defina las propiedades comunes entre Empleado y Cliente así como los métodos que implementan los procesos de Alta, Baja, Cambio de la tabla Persona; adicional a esto se deben crear las clases Empleado y Cliente, ambas heredan de Persona. Cada una deberá definir las propiedades que los diferencian y sobrescribir los métodos Alta, Baja y Cambio de la clase padre, en la sobre escritura de los métodos, se tendrá que hacer una llamada al método base correspondiente y agregar la implementación para modificar la tabla correcta.

Solución con Interfaces: Se debería de crear una interface llamada IPersona y que defina las firmas de los procesos de Alta, Baja, Cambio; adicional a esto se deben crear las clases Empleado y Cliente, ambas que implementen la interface IPersona. Cada una deberá definir las propiedades y campos comunes tanto comunes como diferentes, ambas también deben codificar la implementación de los métodos Alta, Baja y Cambio que realizarán los procesos en la tabla Persona y en la tabla correspondiente.

Conclusión: Cómo se puede ver, utilizando clases abstractas se puede reutilizar mucho código al heredar los campos, propiedades y llamando a los métodos de la clase base; en cambio con interfaces tenemos que re-escribir los campos y propiedades comunes en todas las clases así cómo el código de los métodos.

Funcionalidad Común

Si la funcionalidad que está creando va a ser útil en una amplia gama de objetos diferentes, utilice una interfaz. Las clases abstractas deben utilizarse principalmente para objetos estrechamente relacionados, mientras que las interfaces son más adecuadas para proporcionar funcionalidad común a clases no relacionadas.   

Ejemplo: Se tiene el caso de querer implementar diferentes medios de transporte que existen y se han identificado el Autobus, Avión y Barco. ¿Cómo se implementaría con clases abstractas y cómo con interfaces?

Solución con Clases Abstractas: Se crearía una clase abstracta llamada Transporte que defina el método abstracto Transportar; Se crearán las clases Autobus, Avion y Barco, todas ellas heredarán de Transporte y deberán realizar la implementación del método abstracto.

Solución con Interfaces: Se debería de crear una interface llamada ITransporte que defina la firma del método Transportar; Se crearán las clases Autobus, Avion y Barco, todas ellas implementarán la interfaz ITransporte.

Conclusión: A simple vista se podría decir que ambas soluciones son iguales, ya que las dos le delegan la responsabilidad de implementar el método Transportar a las clases finales Autobus, Avion y Barco, pero la diferencia está en lo siguiente, ¡No existe herencia múltiple! Por lo tanto con la solución de clases abstractas estaremos desperdiciando una oportunidad de heredar de otra clase, pensemos en este caso, podríamos tener una clase padre llamada Avion y las clases hijas Avioneta, AvionComercial, etc., entonces hazte la siguiente pregunta ¿Avioneta y AvionComercial deberían heredar de Avion o de Transporte? En este caso claramente se ve que la mejor opción es utilizar interfaces.

Pequeña Funcionalidad

Si va a diseñar fragmentos pequeños y concisos de funcionalidad, utilice interfaces. Si va a diseñar unidades funcionales grandes, utilice una clase abstracta.

Conclusión: Esta recomendación va muy ligada a las dos anteriores, mientras más grande la funcionalidad es más recomendable la reutilización por lo que las clases abstractas son la mejor opción; con funcionalidad pequeña no es recomendable perder la oportunidad de heredar nuestra clase con una clase padre que tenga una funcionalidad grande para reutilizar sus propiedades y métodos por lo que la utilización de interfaces es nuestra mejor opción.

Funcionalidad común

Si desea proporcionar funcionalidad común e implementada en todas las implementaciones del componente, utilice una clase abstracta. Las clases abstractas permiten implementar parcialmente una clase, mientras que las interfaces no contienen ninguna implementación para ningún miembro.

Conclusión: Siempre que encuentres funcionalidad común entre dos o más clases, busca la manera de utilizar herencia para la reutilización de código (mientras menos escribas mejor).

Si deseas el código fuente utilizado para este discusión puedes descargarlo de:


Actualmente calificado con 4.2 por 5 personas

  • Currently 4,2/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

‘Aplicaciones Dinámicas’ con .NET Reflection y su Rendimiento

febrero 11, 2009 06:38 by Admin

Enviado por Johnatan Flores Carmona el 19 de enero de 2009 

Saludos a todos, antes que nada quisiera comentar que felicito a los propietarios de este grupo así cómo a los usuarios por esta nueva etapa ahora en 'Live'. He sido miembro de este grupo desde ya algunos años y aunque mi participación ha sido casí nula me gustaria pensar "Año Nuevo, Grupo Nuevo, Actitud Nueva" así que para empezar con la nueva actitud, me gustaría compartir con ustedes algo que he tenido que a prender por las malas: El maravillos mundo de .NET Reflection........

Problema:

Actualmente en la institución donde laboro me asignaron a un proyecto que consiste en construir un ‘Bridge’ para que la aplicación ‘X’ pudiera comunicarse con la aplicación ‘Y’. Uno de los muchos requerimientos que solicitaron fue: ‘Actualmente debes conectar ‘X’ con ‘Y’, pero este bridge debe servir posteriormente para comunicar a ‘W’ con ‘Z’, ‘Y’ con ‘W’, etc. por lo que debe ser una aplicación que su funcionalidad deba ser configurable desde base de datos. ¿Cuál fue la solución a estos requerimientos?  R:= .NET Reflection. 

Solución con Reflection:

Implementaciones: Cada uno de las aplicaciones (W, X, Y, Z) tiene sus propias ‘reglas’ de comunicación, por lo que para comunicar XàY se requiere una ‘implementación’ diferente que para comunicar a WàZ y otra totalmente diferente para YàW.

Interfaz de implementación: Todas las implementaciones deberán exponer un método llamado ‘Ejecutar’ el cuál servirá para llevar a cabo los procesos necesarios para cada una de las implementaciones.

Fabrica de implementaciones: Se requiere un método que nos permita obtener la implementación correcta en base a los parámetros de entrada (posiblemente un ID o un nombre).

Diccionario de implementaciones: Requerimos un diccionario que nos permitirá conocer el nombre de la clase que deseamos utilizar para realizar la implementación correcta (en nuestro caso una base de datos o un archivo xml).

Prueba: El método Main que realiza la prueba (hipotetica) de esta solución sería de la siguiente manera:

    class TestRendimientoReflection

    {

        static void Main(string[] args)

        {

            

            //Codigo para medir el tiempo de ejecucion

            EjecutarTest(totalIteraciones);

        }

        static void EjecutarTest(int totalIteraciones)

        {

            Random generadorIdentificadores = new Random();

            for (int i = 0; i < totalIteraciones; i++)

            {

                int idClase = generadorIdentificadores.Next(1, 11);

                IImplementacion clase = FabricaImplementacion.CrearImplementacion(idClase);

                Console.WriteLine(clase.Ejecutar());

            }

        }

    }

Solución sin Reflection:

Implementaciones: (Igual que con Reflection)

Interfaz de implementación: (Igual que con Reflection)

Prueba: El método Main que realiza la prueba de esta solución (hipotetica) sería de la siguiente manera:

    class TestRendimientoSinReflection

    {

        static void Main(string[] args)

        {

            

            //Codigo para medir el tiempo de ejecucion 

            EjecutarTest(totalIteraciones);

        }

        static void EjecutarTest(int totalIteraciones)

        {

            Random generadorIdentificadores = new Random();

            for (int i = 0; i < totalIteraciones; i++)

            {

                int idClase = generadorIdentificadores.Next(1, 11);

                IImplementacion clase = null;

                switch (idClase)

                {

                    case 1:

                        clase = new Implementacion01();

                        break;

                    case 2:

                        clase = new Implementacion02();

                        break;

                    //Todos los case necesarios

                    default:

                        clase = new Implementacion10();

                        break;

                }

                Console.WriteLine(clase.Ejecutar());

            }

        }

    }

Rendimiento:

Cuando se me cuestionó sobre si la utilización de Reflection afectaría el rendimiento que podría tener la aplicación tuve que investigar sobre dicho tema y encontré la siguiente referencia: .Net Reflection and Performance

En este enlace menciona que los procesos de obtener y asignar valores a propiedades con reflection resultó de 2.5 a 3 veces más lento que hacerlo directamente; además de que la invocación de métodos fue 3.5 a 4 veces más lento con reflection que realizar una llamada directa al método.

Estos resultados claramente no son satisfactorios para una aplicación que posiblemente tendría que atender cientos o miles de peticiones, pero también no es nuestro caso la asignación o lectura de propiedades ni mucho menos la ejecución de métodos utilizando reflection. Los datos que necesitábamos conocer era el rendimiento al instanciar clases utilizando reflection.

A continuación los datos que fueron obtenidos:

Rendimiento de Reflection
  Prueba con Reflection Prueba sin Reflection
Total iteraciones 10,000 10,000
Total de Pruebas 20 20
Promedio (ms): 3,813.44 3,706.60
Media (ms): 3,793.24 3,592.44
Mediana (ms): 3,914.25 3,867.38

 Con estos datos se puede decir que el rendimiento de instanciar clases utilizando reflection es de 0.01 a 0.06 veces más lento que creando las instancias directamente. 

Beneficios:

A continuación mencionaré algunas métricas que son utilizadas en el desarrollo de software que están ligadas al código fuente y cómo el uso de Reflection podria ayudar a mejorarlas:

Mantenibilidad: Cómo se puede observar, ambos códigos (con Reflection y sin él) son fácilmente mantenibles ya que si existe un cambio en los procesos de una implementación, sólo tendríamos que modificar la clase correspondiente.

Complejidad Ciclomática: Esta métrica se ve mejorada al utilizar reflection ya que cómo podemos observar no necesitaremos la sentencia ‘switch / case’ para la creación de los objetos con las implementaciones deseadas.

Líneas de código: Las líneas de código también se ven reducidas considerablemente al hacer uso de Reflection.  }

Bajo acoplamiento: Debido a que la construcción se basa en un 'diccionario' de implementaciones, si se deseara que los procesos requeridos para comunicar X con Y ya no es la clase 'ImplementacionXY y en su lugar se utilizaría NuevaImplementacionXY; utilizando Reflection sólo se tendría que modificar el diccionario y no todas las porciones de código que hicieran referencia a esa clase (cómo sería con la instanciación directa). 

Conclusiones:

Utilizar .NET Reflection indiscriminadamente en nuestras aplicaciones hará que el rendimiento de ejecución sea bastante pobre; sin embargo, si se planea bien las arquitectura y las estrategias para utilizar .NET Reflection, el costo de utilizar esta poderosa API no es alto si se consideran los beneficios que se pueden obtener.

Si se desea conocer las buenas practicas de programación al utilizar reflection, pueden leer este excelente artículo: Dodge Common Performance Pitfalls to Craft Speedy Applications

Código Fuente:


Actualmente calificado con 5.0 por 1 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Qué es ASP .NET Control Extenders?

febrero 11, 2009 06:29 by Admin
Aqui dejamos un aporte de la comunidad enviado a través de la seccion de Foro (foro.barreteros.net), este fue enviado por nuestro amigo Johnatan Flores Carmona [johnatan.jfk@gmail.com], el es un Desarrollador .NET de la ciudad de León Guanajuato, aquí dejo el aporte:
------------------------------------------------------------------------------------------
Saludos a todos de nuevo, espero que tengan un bonito día festivo. Y ya que yo tuve que venir a trabajar a pesar de que toda la empresa descansó, estoy aquí para compartir con ustedes otro tema que tuve que investigar hace un tiempo, espero les sea de utilidad. 

  

Qué es ASP .NET Control Extenders?

ASP .NET Control Extenders son controles que derivan de la clase base ExtenderControl (System.Web.UI) la cual puede ser usada para agregar funcionalidad adicional (usualmente soporte AJAX o JavaScript) a controles declarados dentro de una pagina. Esto habilita a los desarrolladores el encapsulamiento de comportamientos IU, y hacer muy fácil agregar funcionalidad a una aplicación web. Un ejemplo de esto es el ASP .NET AJAX Control Toolkit (1)

Según MSDN Library: "La clase ExtenderControl permite mediante programación agregar funcionalidad AJAX a un control de servidor ASP .NET. El ExtenderControl hereda desde la clase Control e implementa la interfaz IExtenderControl. La clase Control define las propiedades, métodos y eventos que son compartidos por todos los controles de servidor ASP .NET. La interfaz IExtenderControl es una clase abstracta la cual no puede ser instanciada directamente. En su lugar debes crear un tipo derivado." (2)

  

Pasos para crear un control extendido

  1. Crear clase abstracta base que hereda ExtenderControl
  2. Crear el archivo .js que implementará el comportamiento de IU (ECMAScript)
  3. Crear una clase que herede de la clase creada en 1 la cual será el extensor del control.
  4. Utilizar el control en una pagina .aspx

En las siguientes secciones se explicarán los pasos necesarios para crear un extensor de control que permite cambiar el estilo al control cuando el mouse pase encima de el.

  

Crear clase base que hereda de ExtenderControl

Cuando se crea una clase que herede de ExtenderControl se requiere que se implementen los métodos abstractos GetScriptDescriptor y GetScriptReferences.

public abstract class ExtenderControlBase : ExtenderControl
{
   protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
   {
      throw new NotImplementedException();
   }
   protected override IEnumerable<ScriptReference> GetScriptReferences()
   {
   throw new NotImplementedException();
   }
}
  • GetScriptDescriptor: Método usado para obtener una colección de descriptores script que representan los componentes cliente ECMAScript (JavaScript).
  • GetScriptReferences: Método usado para obtener una colección de objetos ScriptReference que definen los recursos script que el control requiere.

  

GetScriptDescriptors

Este método debe regresar una colección de objetos ScriptDescriptor que definen que propiedades serán pasadas a la representación del control en el lado del cliente.

protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
{
   ScriptControlDescriptor descriptor = new ScriptControlDescriptor(this.GetType     
                                          ().FullName, targetControl.ClientID);
   descriptor.AddProperty("id", this.ClientID);
   PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this);
   foreach (PropertyDescriptor property in properties)
   {
      ExtenderControlPropertyAttribute propertyAttribute =
            property.Attributes[typeof(ExtenderControlPropertyAttribute)] as
            ExtenderControlPropertyAttribute;
      if (propertyAttribute != null)
      {
          object value = property.GetValue(this);
          string name = (propertyAttribute.Name != null) ?
                            propertyAttribute.Name : property.Name;
      if (value != null)
             descriptor.AddProperty(name, value);
   }
   }
   yield return descriptor;
}

En el código anterior se crea el objeto que contendrá todas las propiedades que contendrá nuestro control; para ello se obtiene la colección de propiedades que contiene nuestra clase (la clase hija que se creará en el paso 2). Una vez obtenida la colección se recorrerán cada uno de los objetos contenidos y se agregan al descriptor con el método .AddProperty

  

GetScriptReferences

Este método regresará una colección de objetos ScriptReference para incluirlos en la pagina del lado del cliente.

protected override IEnumerable<ScriptReference> GetScriptReferences()
{
   object[] scriptReferences = Attribute.GetCustomAttribute(
   this.GetType(), typeof(ScriptReferenceAttribute), false);
   foreach (ScriptReferenceAttribute sra in scriptReferences)
       yield return sra.GetScriptReference();
}

  

Crear el archivo ECMAScript

Este archivo es el que contiene todo el código (JavaScript) que controla los comportamientos que tendrá el control extendido. A continuación se presenta el bloque de código base que debe tener este archivo.

Type.registerNamespace("CustomAjaxControlKit");
CustomAjaxControlKit.MouseOverExtender = function(element){
   CustomAjaxControlKit.MouseOverExtender.initializeBase(this,[element]);
};
CustomAjaxControlKit.MouseOverExtender.prototype = {
   initialize: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "initialize");
   },
   dispose: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "dispose");
   }
};
CustomAjaxControlKit.MouseOverExtender.registerClass  
      ("CustomAjaxControlKit.MouseOverExtender", Sys.UI.Behavior);
Sys.Application.notifyScriptLoaded();

El código anterior debe modificarse para que se vea cómo el código siguiente:

Type.registerNamespace("CustomAjaxControlKit");
CustomAjaxControlKit.MouseOverExtender = function(element){
   CustomAjaxControlKit.MouseOverExtender.initializeBase(this, [element]);
   this._MouseOverCssClass = null;
   this._MouseOutCssClass = null;
   this._mouseOverHandler = Function.createDelegate(this, this._onMouseOver);
   this._mouseOutHandler = Function.createDelegate(this, this._onMouseOut);
};
CustomAjaxControlKit.MouseOverExtender.prototype = {
   initialize: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "initialize");
      var targetElement = this.get_element();
      $addHandler(targetElement, "mouseover", this._mouseOverHandler);
      $addHandler(targetElement, "mouseout", this._mouseOutHandler);
},
   dispose: function(){
      var targetElement = this.get_element();
      $removeHandler(targetElement, "mouseover", this._mouseOverHandler);
      $removeHandler(targetElement, "mouseout", this._mouseOutHandler);
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "dispose");
   },
   get_MouseOverCssClass: function(){
      return this._MouseOverCssClass;
   },
   set_MouseOverCssClass: function(value){
      this._MouseOverCssClass = value;
   },
   get_MouseOutCssClass: function(){
      return this._MouseOutCssClass;
   },
   set_MouseOutCssClass: function(value){
      this._MouseOutCssClass = value;
   },
   _onMouseOver: function(eventArgs){
      var targetElement = this.get_element();
      if(targetElement != null)
         targetElement.className = this.get_MouseOverCssClass();
   },
   _onMouseOut: function(eventArgs){
      var targetElement = this.get_element();
      if(targetElement != null)
         targetElement.className = this.get_MouseOutCssClass();
   }
};
CustomAjaxControlKit.MouseOverExtender.registerClass     
                     ("CustomAjaxControlKit.MouseOverExtender", Sys.UI.Behavior);
Sys.Application.notifyScriptLoaded();

  

Crear la clase que será el extensor del control

Debido a que se creó una clase abstracta base que hereda de la clase ExtenderControl (véase el paso 1), la creación de nuestra clase que será el extensor de control simplemente debe agregar la WebReference del archivo ECMAScript, heredar la clase ExtenderControlBase y agregar las declaraciones de las propiedades que tendrá nuestro extensor de control.

A continuación se muestra el código de nuestra clase:

[assembly: WebResource("CustomAjaxControlKit.MouseOver.MouseOverBehavior.js",
                                                         "text/javascript")]
namespace CustomAjaxControlKit
{
   [TargetControlType(typeof(Control)), ScriptReference(
        "CustomAjaxControlKit.MouseOver.MouseOverBehavior.js", CustomAjaxControlKit")]
   public class MouseOverExtender : ExtenderControlBase
   {
      [ExtenderControlProperty]
      public string MouseOverCssClass { get; set; }
      [ExtenderControlProperty]
      public string MouseOutCssClass { get; set; }
   }
}

  

Utilizar el extensor de control en una pagina .aspx

Para poder utilizar nuestro extensor de control en una pagina .aspx tenemos que primero agregar la referencia al dll que contiene el código de nuestro extensor. Una vez realizado esto se debe incluir la directiva @Register para poder incluir en la pagina los tags de nuestro control: 

<%@ Register Assembly="CustomAjaxControlKit" Namespace="CustomAjaxControlKit" TagPrefix="cack" %>
Por último debemos agregar el control que sufrirá los efectos de nuestro extensor y a continuación declarar nuestro control:
<asp:Label runat="server" ID="Label1" Text="Texto prueba" />
<cack:MouseOverExtender ID="MouseOverExtender1" runat="server" TargetControlID="Label1"  MouseOutCssClass="MouseOutStyle"
                       MouseOverCssClass="MouseOverStyle" />

  

Ejemplo: Codigo Fuente

Si deseas ver el código fuente completo de este control puedes descrgarlo en el siguiente link:

  

Referencias

  1. ScottGu; Using ASP .NET AJAX Control Extenders in VS 2008; http://weblogs.asp.net/scottgu/archive/2007/08/19/using-asp-net-ajax-control-extenders-in-vs-2008.aspx
  2. MSDN Library; About ExtenderControl Class; http://msdn.microsoft.com/en-us/library/system.web.ui.extendercontrol.aspx

Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Filtros inteligentes de Office 2007, para Windows Desktop Search

octubre 24, 2008 05:19 by cesar

Bueno, Microsoft acaba de liberar un filtro inteligente para Windows Desktop Search ( Parte de Windows XP y Vista como actualización, actualmente vamos en la versión 4) que te permite buscar dentro de los archivos de office con las siguientes extensiones: .docx, .docm, .pptx, .pptm, .xlsx, .xlsm, .xlsb, .zip, .one, .vdx, .vsd, .vss, .vst, .vdx, .vsx, and .vtx.( Versiones de Archivo de Office 2007).

Esta actualización registrará automáticamente los IFilters dentro del Servicio de Indexación de Windows, que es lo que utiliza WDS para realizar las búsquedas.

Para descargar esta actualización, haz clic aquí

Si aún no tienes Windows Desktop Search v4, puedes descargarlo aquí y elige la versión adecuada para tu computadora.


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Material Curso ASP.NET ITZ 2008

octubre 24, 2008 05:10 by Admin

Material del Curso ASP.NET ITZ 2008
Tercera Sesion 21 de Octubre de 2008

Introducción a la plataforma .NET de Microsoft Introducción a la plataforma .NET de Microsoft
Temas analizados:

  • Conceptos básicos ASP.NET
  • Generalidades de HTTP
  • HTML Forms
  • Webforms
  • Controles básicos
  • Programación en Code-Behind

Click para descargar: Office 2007

PaqueteZIPHolaMundo2
Contenido del paquete:

  • Conociendo controles HTML y ASP .NET
  • Conociendo el concepto de Postback
  • Uso de controles HTML y ASP.NET combinados
  • Manteniendo estado de controles entre postbacks

Click para descargar: HolaMundo2.zip

 


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Material Curso ASP.NET ITZ 2008

octubre 24, 2008 05:10 by Admin

Revisión de material de Curso .NET ITZ 2008
Ya está disponible la revisión del proyecto “HolaMundo”

PaqueteZIPHolaMundo
Contenido del paquete:

  • Conociendo controles HTML y ASP .NET
  • Conociendo el concepto de Postback
  • Uso de controles HTML y ASP.NET combinados
  • Manteniendo estado de controles entre postbacks

Click para descargar: HolaMundo.zip


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Material de la 1ra clase Curso VB.NET UNID

octubre 20, 2008 02:49 by ddaz

 

 

Les dejo el Material de la Primera Clase del curso presencial de Visual Basic que empezamos a dictar en la UNID sede Zacatecas, esta clase fue la introducción, además les dejo el archivo con los ejemplos, las imágenes que hice en el Visual Paint no las grabe, así que no las pude subir :),  no se olviden llegar temprano a la próxima clase, ya que los 45 primeros minutos se realizara la practica guiada de lo que se toco en esta clase, y luego se continuara con el tema de la clase,  no se olviden de hacer la tarea, y de enviarla al email.

seria bueno que vayan adelantando, leyendo el curso de Vb que esta en la Web de El Guille ( http://elguille.info/NET/cursoVB.NET/indice.htm )

Hoy me encargue personalmente de instalar el Visual Basic Express en el Laboratorio de la UNID, así en la próxima clase podremos hacer los ejercicios.

 

Los Temas que se vieron esta semana:

  • Reglamento del curso
  • Introducción a .Net
  • Reconocimiento de la Herramienta a Utilizar
  • Clases, Objetos, Namespaces,
  • Variables
  • Tipos por Referencia y por Valor
  • Enumeraciones
  • Tipos de Datos
  • Tipos de Datos Definidos por el Usuario ( Estructuras).
    • Sobre Carga de operadores
    • Constructores  ( algo leve)
  • Control del Flujo de ejecución ( If, for, etc.)

Pueden Descargar el material desde aquí :   Diapositiva  clase 1  y Material Clase 1  :

Los Esperamos la próxima clase.

Salu2

Ddaz


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Aplicaciones Web de Vanguardia con AJAX.NET y Silvelight

octubre 11, 2008 15:31 by sergio

Aplicaciones Web de Vanguardia con AJAX.NET y Silvelight 
Ya está disponible la presentación de la ponencia en el Simposium de Tecnología del ITZ el 30 de Septiembre.

 

Aplicaciones Web de Vanguardia
  • Introducción
  • El modelo AJAX
  • Cambiando el Paradigma
  • AJAX vs Aplicaciones Web Clásicas
  • ¿Por qué Silverlight?
  • Experiencia de Usuario con Silverlight
  • La Web se pone Interesante

Click para descargar:  Office 2007


Actualmente calificado con 5.0 por 2 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5