Buscar este blog

martes, 23 de octubre de 2012

Agregar método extendido a un objeto (clase o control) en C#

Hoy veremos como agregar un método adicional a un clase o control que no son propios de nuestro código  por ejemplo podríamos agregar una extensión a la clase DataTable que permita convertir todos sus datos a un XML, o agregar una extensión a un GridView para poder exportar a Excel. Estos tipos de métodos son muy útiles para encapsular una funcionalidad común para un tipo de objeto en especifico.

Ejemplo:
Primero agregamos una clase nueva a nuestro proyecto "ListBoxExtension", esta clase tendrá todos los métodos extendidos del control ListBox.

public static class ListBoxExtension
    {
        public static string ConvertToXml(this GandA.Web.UI.Controls.ListBox listBox)
        {
            string xml = string.Empty;
            foreach (ListItem item in listBox.ControlListBox.Items)
            {
                xml = xml + "<Item><Value>" + item.Value + "</Value></Item>";
            }

            if (!string.IsNullOrEmpty(xml))
                xml = "<Items>" + xml + "</Items>";

            return xml;
        }
}

Como pueden observar, para decir que nuestro método sera un extensión recibe como parámetro el control anteponiendo la palabra "this".
Si queremos utilizar el método, lo haremos de la siguiente manera:

protected void btnGuardar_Click(object sender, EventArgs e)
{
     lstEstPaq.ConvertToXml();
}

Donde "lstEstPaq", es nuestro control ListBox, y "ConvertToXml" es nuestro extension. Podrán observar que este método sólo va a aparecer si se esta haciendo referencia a la clase ListBoxExtension, para ello agreguen su using.

using CLab.Utils.Extensions;

Donde "MiProyecto.Utils.Extensions" es mi namespace donde se encuentra mi clase ListBoxExtension.

Como pueden darse cuenta la extensión de métodos es algo muy sencillo de implementar y que nos ayuda a encapsular y agregar funcionalidades extras a clases o controles que no son parte de nuestro código.
Espero que esto les ayude, y cual quier duda preguntes

--------------------------------------------------------------
Lo que se puede imaginar... se puede programar

miércoles, 11 de julio de 2012

Número Aleatorio en C# - Random

Hoy veremos como obtener números aleatorios en C# con la clase Random, esta clase que nos proporciona el framework como verán es muy fácil de utilizar, sólo hay que instanciar un objeto de esta clase y ejecutar el método Next, NextDouble o NextBytes.
Como verán podrán obtener aleatoriamente  números enteros, decimales y arreglos de bytes, aquí les dejo un ejemplo:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Random numAleatorio = new Random();


            // Numero maximo 100
            Console.WriteLine("Numero maximo aleatorio 100");
            Console.WriteLine(numAleatorio.Next(100));


            Console.WriteLine(Char.ToString((char)32));
            Console.WriteLine("Numero aleatorio entre 100 y 1000");
            // Rango de 100 a 1000
            for (int i = 0; i &lt; 10; i++)
            {
                Console.WriteLine(numAleatorio.Next(100, 1000));
            }


            Console.WriteLine(Char.ToString((char)32));
            Console.WriteLine("Numero aleatorio doble(decimal) entre 0 y 1");
            // Numero decimal entre 0 y 1
            Console.WriteLine(numAleatorio.NextDouble());


            Console.WriteLine(Char.ToString((char)32));
            Console.WriteLine("Presione Enter para Salir...");


            int tecla = Console.Read();
        }
    }
}

Espero que esto les sea de utilidad....
-------------------------------------------------
Lo que se puede imaginar... se puede programar

martes, 10 de julio de 2012

Thread C#, Manejo de multiprocesos - hilos en .Net

Hola, hoy veremos como manejar subprocesos en C# para evitar que nuestras pantallas se congelen al hacer una acción, esto aplica tanto para windows forms como para web forms, pero es mas común manejar lo en windows form. El manejo de estos hilos se pueden manejar con la clase Thread, aquí un ejemplo sencillo:

Thread t = new Thread(new ThreadStart(Process)); t.Start();


// Función a ejecutar en un hilo del proceso principal
private void Process()
{
    ////... Código
}

Como verán es muy sencillo ejecutar un método en un subproceso/hilo, con en metodo Start se dara inicio a ese subproceso y con la instrucción Abort, como su nombre lo dice podrás detener el subproceso lanzado de manera explicita. A continuación les dejo un ejemplo mas real de como se comportaría una pantalla si se ejecuta un proceso como subproceso y de manera normal.

using System;
using System.Windows.Forms;
using System.Threading;


namespace Multihilo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private void BtnProcess_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(Process));
            //BtnProcess.Enabled = false;
            t.Start();
            //t.Join();
            //BtnProcess.Enabled = true;


            //Sin Multiproceso
        }


        private void Process()
        {
            double i, j;
            double num=0;
            for (i = 0; i < 10000; i++)
            {
                for (j = 0; j < 90000;j++ )
                    num = i;
            }
            MessageBox.Show("Numero = " + num.ToString());
        }


        private void BtnNormal_Click(object sender, EventArgs e)
        {
            Process();
        }


        private void BtnJoin_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(Process));
            //BtnProcess.Enabled = false;
            t.Start();
            t.Join();
            //BtnProcess.Enabled = true;
        }
    }
}

Espero que esto les sea de utilidad.

Código fuente:
Descargar(en VS2008)
-------------------------------------
Lo que se puede imaginar... se puede programar

viernes, 6 de julio de 2012

Pasar un XML por parámetro a un Stored Procedure en SQLServer 2005

Hola, hoy les traigo algo muy interesante y que me a ayudado mucho a la hora de guardar un conjunto de información que traigo en memoria dentro de mi aplicación. Con esto podran guardar toda su información en una sola llamada al sp, sin necesidad de hacer un ciclo y mandar a llamar el sp n veces por cada registro a insertar.

Ejemplo:
CREATE PROC spTestXML
@psXML NVARCHAR(max)
AS
BEGIN
SET NOCOUNT ON
DECLARE @nIdXml INT
DECLARE @tblRegistros TABLE (Indice INT IDENTITY(1,1), ClaEmpleado INT, Nombre VARCHAR(100))

IF ISNULL(@psXML,'') <> ''
BEGIN
exec dbo.sp_xml_preparedocument @nIdXml OUTPUT, @psXML

INSERT INTO @tblRegistros (ClaEmpleado, Nombre)
SELECT ClaEmpleado, Nombre
FROM OPENXML (@nIdXml, '/Empleados/Empleado', 3)
WITH (ClaEmpleado INT, Nombre VARCHAR(100))

EXEC dbo.sp_xml_removedocument @nIdXml
END

SELECT * FROM @tblRegistros

SET NOCOUNT OFF 
END

Ejecución:
EXEC spTestXML @psXML = '<Empleados>
<Empleado>
<ClaEmpleado>2001</ClaEmpleado>
<Nombre>Hugo</Nombre>
</Empleado>
<Empleado>
<ClaEmpleado>5214</ClaEmpleado>
<Nombre>Paco</Nombre>
</Empleado>
<Empleado>
<ClaEmpleado>7841</ClaEmpleado>
<Nombre>Luis</Nombre>
</Empleado>
</Empleados>'

Puntos importantes:

  • El parámetro del sp sera de tipo VARCHAR o NVARCHAR
  • Hay que ejecutar el sp " sp_xml_preparedocument " el cual te devuelve un ID (sobre este valor se trabaja para obtener los datos)
  • La función  "OPENXML"  y  "WITH"  nos ayudaran a obtener nuestros datos, digamos que nos convierte el xml a una tabla. Esta función recibe como parámetro el ID antes obtenido y un string especificándole la estructura de nuestro xml. En la función  WITH  se especifican los atributos que va a contener los valores del xml, digamos que aquí especificamos el nombre y tipo de dato que recibirá los valores que contiene nuestro xml.
  • " sp_xml_removedocument  ", al final sólo removemos nuestro xml cargado en memoria con ayuda del ID generado con el primer sp.
Como pueden ver el manejo de xml en SQLServer es muy facil y nos puede ayudar en performance, para evitar ciclos inicesarios, si lo que queremos es insertar un conjunto de registro, en lugar de insertar uno por uno sólo sera necesario un INSERT SELECT.

Actualización (chequen esta forma que es mas sencilla de utilizar):
http://ganda-csharp.blogspot.mx/2013/03/pasar-xml-stored-procedure-en-sqlserver.html

Espero que esto les sea de utilidad
----------------------------------------------------------
Lo que se puede imaginar... se puede programar

jueves, 5 de julio de 2012

Leer y escribir en una Cookie desde JavaScript

Hola, hoy les dejo un ejemplo que me pareció muy interesante, leer y escribir en una Cookie desde JavaScript, normalmente cuando leemos una cookie lo hacemos desde código del lado del servidor, pero bueno aqui el ejemplo:

<script language="JavaScript" type="text/javascript">
<!--

readCookie();

function readCookie() {
     if (document.cookie == "") {
writeCookie();
        alertMessage();
     } else {
var the_cookie = document.cookie;
the_cookie = unescape(the_cookie);
the_cookie_split = the_cookie.split(";");
for (loop=0;loop<the_cookie_split.length;loop++) {
var part_of_split = the_cookie_split[loop];
var find_name = part_of_split.indexOf("nfti_date")
if (find_name!=-1) {
break;
} // Close if
} // Close for
if (find_name==-1) {
writeCookie();
} else {
var date_split = part_of_split.split("=");
var last = date_split[1];
last=fixTheDate(last);
alert (" - Bienvenido - Tu última visita a esta página fue: "+last);
writeCookie();
} // Close if (find_name==-1)
      }
} // Close function readCookie()


function writeCookie() {
     var today = new Date();
     var the_date = new Date("December 31, 2023");
     var the_cookie_date = the_date.toGMTString();
     var the_cookie = "nfti_date="+escape(today);
     var the_cookie = the_cookie + ";expires=" + the_cookie_date;
     document.cookie=the_cookie
}

function alertMessage(){
     alert ("Bienvenido\aquí agregas un mensaje de bienvenida.")
}

function fixTheDate(date) {
     var split = date.split(" ");
     var fix_the_time = split[3].split(":")
     var hours = fix_the_time[0]
     if (hours>=12) {
var ampm="PM"
     } else {
var ampm="AM"
     }
     if (hours > 12) {
hours = hours-12
     }
     var new_time = hours+":"+fix_the_time[1]+" "+ampm
     var new_date = split[0]+" "+split[1]+", "+split[2]+" at "+new_time+", "+split[5]
     return new_date;
}
//-->
</script>                 

Para probar el ejemplo hagan copy paste en una pagina y al visualizarla en el explorador presionen F5 para recargar la pagina y el script pueda leer la cookie ya escrita al cargar por primera vez la pagina.

Espero que esto les sea de utilidad
-----------------------------------
Lo que se puede imaginar... se puede programar

miércoles, 4 de julio de 2012

Errores manejados en SQLServer, TRY ... CATCH, RAISERROR

Hola, hoy veremos como manejar los errores en SQLServer 2005, y tambien como lanzar errores personalizados con la instrucción RAISERROR


El Try.. Catch funciona de manera similar como en C#, intenta la ejecución de un bloque de codigo y si marca algún error lo cacha.


Sintaxis en SQL:

BEGIN TRY
     -- Instrucciones
END TRY
BEGIN CATCH
-- Manejo del error
END CATCH

A continuación muestro un ejemplo de como tratar un error que nos arroje SQL. La función ERROR_MESAGE propia de SQLServer contendrá la descripción del error.
Ejemplo, error división entre cero:

BEGIN TRY
SELECT 1/0
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
END CATCH
-----------------------------
Error manejado por usuario
(1 row(s) affected)

Ahora, para lanzar un error manejado por el usuario utilizaremos la funcion RAISERROR, se utiliza para devolver mensajes a las aplicaciones con el mismo formato que un error del sistema o un mensaje de advertencia generado por SQL Server Database Engine.
Ejemplo:


IF (SELECT 10/2) = 5
BEGIN
RAISERROR('Error manejado por usuario',16,1)
END
-----------------------------
Error manejado por usuario

Para mas información de la funcion RAISERROR:
http://msdn.microsoft.com/es-es/library/ms177497(SQL.90).aspx

Espero que esto les sea de utilidad, hasta la próxima publicación.
------------------------------------------
Lo que se puede imaginar... se puede programar

viernes, 29 de junio de 2012

Concatenar valores por comas sin validar si es el primero o ultimo elemento

Para concatenar elementos en SQLServer ya sea separadas por coma u otro carácter de separación podemos utilizar la función COALESCE, esta función es parecido a un CASE, si la primera expresión es nula tomara la siguiente expresión y así de esta manera nos evitaremos validar si es la primera vez para no ponerle el carácter de separación ",".

Ejemplo:
-- Tabla temporal
DECLARE @tblNombres TABLE(Nombre VARCHAR(30))
-- Inserto sus valores
INSERT INTO @tblNombres
        ( Nombre )
SELECT 'Jose'
UNION
SELECT 'Juan'
UNION
SELECT 'Pedro'
UNION
SELECT 'Paco'
UNION
SELECT 'Luis'
SELECT * FROM @tblNombres

-- Aquí la solución sencialla de concatenar sin case o if
DECLARE @sNombres VARCHAR(100)
SELECT @sNombres = COALESCE(@sNombres + ',', '') + Nombre
FROM @tblNombres
SELECT @sNombres AS Nombres


Resultado:
(5 row(s) affected)
Nombre
------------------------------
Jose
Juan
Luis
Paco
Pedro
(5 row(s) affected)

Nombres
----------------------------------------------------------------------------------------------------
Jose,Juan,Luis,Paco,Pedro
(1 row(s) affected)

No se les olvide comentar y darle un +1.

----------------------------------------------------------------------------------------------------
Lo que se puede imaginar... se puede programar

Redondear o truncar decimales en SQLServer

Después de bastante tiempo por fin me doy el tiempo de hacer otra publicación sobre programación, hoy veremos como redondear o truncar decimales en sql.

Con redondeo:
SELECT ROUND(100.4658, 2)
---------------------------------------
100.4700

Truncado:
SELECT ROUND(100.4658, 2, 1)
---------------------------------------
100.4600

Truncar y quitar ceros a la derecha
SELECT CONVERT(FLOAT, ROUND(100.4658, 2, 1))
----------------------
100.46

Espero que estoy les sea de utilidad, y no se olviden comentar y dar un +1.

---------------------------------------------------------------
Lo que se puede imaginar... se puede programar

domingo, 19 de febrero de 2012

Como utilizar el ValidatorCallout de Ajax Control Toolkit

Hoy veremos como utilizar un extender de los controles Validation de asp.net, este control nos ayudara a mostrar una interfaz mas amigable para el usuario, como se muestra en la siguiente imagen:


Como podrán observar en la imagen el controles se muestran marcados en rojo y si alguno de ellos esta en foco se muestra un mensaje en forma de globo, este puede contener una imagen y texto con el error de validación.
Ahora veamos como utilizarlo:

En el aspx

<asp:TextBox ID="TxtUsuario" runat="server" Width="160px" MaxLength="20" CssClass="TextBox"></asp:TextBox>
 <asp:RequiredFieldValidator ID="rfvUsuario" runat="server" ErrorMessage="Nombre de usuario requerido"
            ControlToValidate="TxtUsuario" SetFocusOnError="true" Display="None"></asp:RequiredFieldValidator>
<ajax:ValidatorCalloutExtender ID="ValidatorCalloutExtender1" runat="server" TargetControlID="rfvUsuario"
           HighlightCssClass="validatorCalloutHighlight" CssClass="CustomValidatorCalloutStyle">
</ajax:ValidatorCalloutExtender>

Los estilos que utiliza:
.CustomValidatorCalloutStyle div, 
.CustomValidatorCalloutStyle td { 
    border:solid 1px Gray; background-color: #F7F3F3; 
}

.validatorCalloutHighlight
{
border:solid 1px red;
        background-color: #FFF4F4;
}

Como verán es algo sencillo de utilizar, lo importante aqui es en lazar el control al extender con la propiedad TargetControlID.

Otra cosa importante es que agreguen la referencia del control a la pagina o al Web.config
<pages>
      <controls>
        <add tagPrefix="ajax" namespace="AjaxControlToolkit" assembly="AjaxControlToolkit"/>
        <add tagPrefix="recaptcha" namespace="Recaptcha" assembly="Recaptcha"/>
      </controls>
</pages>

Espero que esto les sea de utilidad y pronto pondre mas ejemplos sobre los controles de Ajax Control Toolkit.

Visiten:

Lo que se puede imaginar ... se puede programar


jueves, 26 de enero de 2012

PageMethods en Asp.Net AJAX


Hola, hoy veremos como utilizar ajax de una manera muy sencilla, esto se logra atreves de los PageMethods, estos se comunicaran con un WebMethod que este en nuestro código de la pagina (del lado del servidor) .

Lo primero que aremos es definir nuestro WebMethod, esto significa que a nuestro método lo decoraremos con el atributo [WebMethod], ejemplo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication2
{
    public partial class _Default : System.Web.UI.Page
    {
        [WebMethod]
        public static List<Persona> SendForm(string name)
        {
            ////return name + " - Fue al servidor";
            List<Persona> p = new List<Persona>();
            p.Add(new Persona("Nombre 1", 26));
            p.Add(new Persona("Nombre 2", 26));
            return p;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
        }
    }

    public class Persona
    {
        public Persona()
        {

        }

        public Persona(string nombre, int edad)
        {
            Nombre = nombre;
            Edad = edad;
        }
        public string Nombre
        {
            get; set;
        }

        public int Edad
        {
            get; set;
        }

    }
}

Cabe aclarar que un un PageMethod podrá retornar casi cualquier tipo de datos que regrese el WebMethod, en este ejemplo retorna una lista de objetos de tipo Persona.

Ahora del lado del cliente definimos lo siguiente:
      1. Habilitar los PageMethods
Lo que hay que hacer para permitir PageMethods es prender una propiedad de nuestro ScriptManager.

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
                        <Scripts>
                                  <asp:ScriptReference Path="~/Scripts/Default.js" />
                       </Scripts>
           </asp:ScriptManager>

           Tambien aprovechamos para hacer referencia a nuestro js que contiene las funciones que utilizaremos.
      
      2. Crear nuestro script (Default.js)
             Esta es la función que llamaremos desde el click de un botón (el nombre es indistinto), el objeto PageMethods contiene los webMethods que tengamos en nuestro codigo de la pagina (en el .cs)
function SendForm() {
    var name = $get(textBox1).value;
    PageMethods.SendForm(name, OnSucceeded, OnFailed);
}
Las funciones de OnSucceeded y OnFailed deben ser incluidas como parámetros en la ejecución de nuestro PageMethod PageMethods.SendForm(name, OnSucceeded, OnFailed), y el primer parámetro es parte de nuestro WebMethod.

Esta function cacha el resultado de nuestro webMethod:
function OnSucceeded(lista) {
    $get(lblPrueba).innerHTML = string;
}

Esta function es utilizada para cachar un possible error:
function OnFailed(error) {
    alert(error.get_message());
}

      3.  En el aspx:
     <p>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="SendForm();" />
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:Label ID="LblPrueba" runat="server" Text="Label"></asp:Label>
    </p>
    <script type="text/javascript">
        var lblPrueba = '<%=LblPrueba.ClientID %>';
        var textBox1 = '<%=TextBox1.ClientID %>';
    </script>

Como ven esta manera de utilizar ajax es muy facil y te olvidas de mandar a llamar un pagina y en el load procesar la petición... entre otras cosas, de esta forma el codigo queda en la misma pagina y se manda a llamar de una manera transparente.
Espero que esto les sea de utilidad.

Lo que se puede imaginar ... se puede programar