Archive for junio 2011

Invocando un Servicio WCF Asincrónicamente


En WCF existen varias formas para consumir un servicio de forma asincrónica. La más simple quizás es poner el asincronismo del lado del cliente, que es lo que vamos a hacer en este post.
Para iniciar vamos a crear un proyecto del tipo WCF ServiceLibrary y vamos a crear un servicio muy simple que tiene solamente un método que retorna el número de frutas – strings – que se lo soliciten vía parámetro a la operación. La interface – contrato – del servicio se ve a continuación:
[ServiceContract(Namespace="http://drojasm.net")]
public interface IServicioProductos{
    [OperationContract]
    List<string> ObtenerProductos(int pCantidad);
}

Seguidamente procedemos con el código para implementar la operación. Como podemos ver en el siguiente código, este simplemente lo que hace es hacer un for y agregar un string a la lista por cada iteración. Nótese además la línea en donde ponemos a dormir el thread del servicio, esto con el fin de que nos de tiempo de hacer algo diferente en el UI mientras el servicio se ejecuta.
public class ServicioProductos : IServicioProductos
    {
        public List<string> ObtenerProductos(int pCantidad)
        {
            List<string> _productos = new List<string>();

            for (int i = 0; i < pCantidad; i++)
            {
                _productos.Add("Fruta Número " + i.ToString());
            }

            System.Threading.Thread.Sleep(5000);
            return _productos;

        }
    }
}

Ahora vamos a proceder a crear el cliente que va a consumir el servicio. En este caso vamos a utilizar una aplicación WPF. Lo primero que vamos a hacer después de crear la aplicación es agregar una referencia al servicio como se hace tradicionalmente; es decir, botón derecho sobre el proyecto, seleccionar agregar referencia, y en la pantalla de configuración de la referencia del servicio, poner la dirección del servicio – en este caso hosteado en el wcfsvchost – y por último obtener el wsdl del mismo.

image

Sin embargo, esta vez vamos a seleccionar además el botón de “Advanced” para configurar la generación del proxy. Luego en esta pantalla vamos a configurar la generación del proxy, seleccionando en esta la opción para generar clientes asincrónicos. Esta opción nos va a generar además de los métodos tradicionales sincrónicos, los métodos necesarios para invocar el servicio utilizando asincronismo.

image

Luego seleccionamos Ok en las siguientes dos pantallas y se procede con la generación del proxy. Como podemos ver en la siguiente figura, el proxy genera los métodos para consumir asincrónicamente el servicio.

image

Ahora procedemos a crear la pantalla en WPF para invocar el servicio. Para esto, vamos a agregar un listbox en donde pintamos el resultado de cada servicio. Además vamos a poner un textbox para que el usuario – yo Sonrisa - digite cuantos elementos quiere en la lista. También vamos a poner dos botones, uno para invocar el servicio sincrónicamente y otro asincrónicamente. Por último, vamos a poner un botón que va a lanzar un MessageBox cuando se le da click; el objetivo de este es demostrar que cuando invocamos el servicio de forma asincrónica, podemos llevar a cabo otras tareas mientras que cuando lo hacemos de forma sincrónica la pantalla se bloquea. El XAML de la pantala es el siguiente:
<Window x:Class="ClienteAsincronicoWCF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="447">
    <Grid>
        <ListBox Height="197" HorizontalAlignment="Left" Margin="47,74,0,0" Name="lstFrutas" VerticalAlignment="Top" Width="120" />
        <Label Content="Frutas" Height="28" HorizontalAlignment="Left" Margin="47,40,0,0" Name="label1" VerticalAlignment="Top" />
        <Button Content="Cargar Sincronicamente" Height="23" HorizontalAlignment="Left" Margin="213,220,0,0" Name="btnSincronico" VerticalAlignment="Top" Width="140" Click="btnSincronico_Click" />
        <Button Content="Cargar Asincronicamente" Height="23" HorizontalAlignment="Left" Margin="213,249,0,0" Name="btnAsincronico" VerticalAlignment="Top" Width="140" Click="btnAsincronico_Click" />
        <Label Content="Cantidad de Productos" Height="28" HorizontalAlignment="Left" Margin="213,146,0,0" Name="label2" VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="213,180,0,0" Name="txtCantidad" VerticalAlignment="Top" Width="140" />
        <Button Height="75" HorizontalAlignment="Left" Margin="269,40,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click">
            <Button.Content>
                <StackPanel>
                    <Image Height="48" Name="image1" Stretch="Fill" Width="48" Source="/ClienteAsincronicoWCF;component/pens.png" />
                    <Label Content="Otra Tarea" Height="28" Name="label3" />
                StackPanel>
            Button.Content>
        Button>
    Grid>
Window>

Y la pantalla en modo de diseño es la siguiente:

image

El código del botón para la invocación sincrónica del servicio es el siguiente:
private void btnSincronico_Click(object sender, RoutedEventArgs e)
{
    lstFrutas.ItemsSource = null;
    ServicioProductosClient _proxy = new ServicioProductosClient();
    lstFrutas.ItemsSource =  _proxy.ObtenerProductos(int.Parse(txtCantidad.Text));
}

No olvidar agregar el namespace del servicio – el que digitamos en la pantalla para agregar la referencia al mismo.
using ClienteAsincronicoWCF.ReferenciaServicioProductos;

Como podemos ver en el código del botón, la forma de invocar este servicio es la tradicional; este procedimiento bloquea la pantalla y no permite realizar ninguna otra tarea mientras la invocación al servicio se esta ejecutando.

image

Ahora procedemos a agregar el código de la llamada asincrónica.
private void btnAsincronico_Click(object sender, RoutedEventArgs e)
{
    lstFrutas.ItemsSource = null;
    ServicioProductosClient _proxy = new ServicioProductosClient();
    AsyncCallback _callBack =
        delegate(IAsyncResult pResult)
        {
            this.Dispatcher.BeginInvoke((Action)delegate { lstFrutas.ItemsSource = _proxy.EndObtenerProductos(pResult); });                    
        };

    _proxy.BeginObtenerProductos(int.Parse(txtCantidad.Text), _callBack, _proxy);           
}

En este código nos vamos a detener un momento para analizarlo un poco mas detalladamente. En primera instancia procedemos a crear un delegate en donde vamos a obtener la respuesta del servicio. En este delegate además, debemos hacer un llamado a la operación BeginInvoke porque el thread en donde se invoca el proceso es diferente al thread del UI, por lo tanto no se puede asignar el resultado directamente a la lista. Por último, invocamos el servicio de forma asincrónica utilizando el método BeginObtenerProductos.

En el botón del MessageBox tenemos el siguiente código:
private void button1_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Iniciando otra operación");
}

Ahora procedemos a ejecutar el servicio con el botón btnAsincronico. Como podemos ver en la siguiente imagen, se pudo invocar al messageBox mientras el servicio estaba procesándose.

image


miércoles, junio 29, 2011
Posted by Carlos
Tag :

Saving changes is not permitted. The changes that you have made require the following tables to be dropped and re-created

ERROR:

“Saving changes is not permitted. The changes that you have made require the following tables to be dropped and re-created. You have either made changes to a table that can’t be re-created or enabled the option Prevent saving changes that require the table to be re-created.”
This error happens because “Saving Changes is not permitted” when using SQL Server 2008 Management Studio to modify the structure of a table especially when SQL Server needs to drop and recreate a table to save the structural changes. It is always advised to make a structural change for a table using TSQL. However, it is a convenient option for database developers to use SQL Server Management Studio make such changes  as the Prevent Saving Changes That Require Table Re-creation  option is enabled by default in SQL Server 2008 Management Studio.
Disable “Prevent saving changes that require the table re-creation” 
1.    Open SQL Server 2008 Management Studio (SSMS). Click Tools menu and then click on Options… as shown in the snippet below.

2.    In the navigation pane of the Options window, expand Designers node and select Table and Database Designers option as shown in the below snippet. Under Table Options you need to uncheck “Prevent saving changes that require the table re-creation” option and click OK to save changes.
This option when enabled prevents users from making structural changes to table using SQL Server Management Studio especially when SQL Server needs to recreate the table to save changes. By default, this option is checked and you need to uncheck this option to allow users to make any structural change through SSMS that   require table recreation.
A table needs to be recreated whenever any of the below   changes are made to the table structure.
·         Insert a new column in the middle of the table.
·         Add a new column in the table.
·         Change the Allow Nulls setting of a column.
·         Modify the identity property of a column.
·         Reorder the columns within a table.
·        Modify the datatype of a column.
Once you have disabled “Prevent saving changes that require the table re-creation” option you can go ahead and save the changes to the Employee Table. This will create a Validation Warning dialog box as shown in the below snippet. The warning message will be “One or more existing columns have ANSI_PADDING ‘off’ and will be re-created with ANSI_PADDING ‘on’”. Click “Yes” to save the changes.
Risks of Turing Off “Prevent Saving Changes that Require Table Re-creation” in SSMS
If you turn off this feature then you can avoid table recreation. However, if you have the Change Tracking feature of SQL Server 2008 enabled to track the table changes then the change tracking information will be lost completely whenever table is recreated. So, it is always advised to use this feature very carefully especially in a production environment.
Posted by Carlos

Cambiar el lenguaje de un sitio de Windows Sharepoint Services 3.0

Si estás leyendo esta página es muy probable que tu sitio de SharePoint WSS 3.0 se encuentre en un lenguaje distinto al que tu quieres por ejemplo tengo mi sitio de SharePoint en Ingles pero deseo cambiarlo a español y lo peor es que el sitio está lleno de información está en producción y está altamente personalizado, Instalaste el language pack en español pero no paso nada. Pues estas en el lugar apropiado para solucionar el incidente.

1. Instalar el Language Pack en español

En el sitio de la descarga, asegúrate deseleccionar el lenguaje Spansih



2. Instalar En el servidor el SQL Server Management Studio Express


3. Instalar el SQL Server Native Client

Clic aqui para ir al sitio de descarga

Una vez instalado, Abrir el Sql Server Management Studio Express y Conectarse a la instancia de SharePoint v3 con el canal named pipe, para esto, mirar en el registro (Inicio/Ejecutar Regedit) y navegar en la siguiente direccion:

HKEY_LOCAL_MACHINE
SOFTWARE
MicrosoftMicrosoft SQL Server
MICROSOFT##SSEE
MSSQLServer
SuperSocketNetLib
Np

Abrir la key llamada NamedPipe y copiar el contenido de esa key
Cierre el Editor de Registro de Windows.

4. Abra el sql server management studio express



Conectarse con los siguientes parametros:
Server Name: el named pipe que copiaste en la key NamedPipe del regedit
Autenticación: windows
Clic en Conectar


5. Cambiar el lenguaje


Navegar hasta la base de datos wss_content

Buscar la tabla dbo.webs y darle clic derecho abrir




Buscar el campo LANGUAGE y LOCALE y cambiarlos por el id del lenguaje en español tradicional es decir el 3082 el ingles Eu es el 1033

Esta tarea se puede hacer con un QUERY
UPDATE DBO.WEBS SET LANGUAGE = 3082, LOCALE = 3082
Cierre el SQL Server Management Studio Express.

6. Abra el sitio de SharePoint que estaba en Ingles

Hasta el momento hemos hecho la mayor parte del trabajo lo que sigue a continuación es revisar el sitio y mirar que algunos formularios tienen contenido en ingles, esto es por que cuando sitio del lenguaje anterior fue creado, el SharePoint generó unos formularios bajo los cuales incluyo el lenguaje Ingles por lo tanto, es necesario abrirlos con el SharePoint Designer y cambiar a mano el contenido de español a Ingles.


Eider Mauricio Aristizabal


martes, junio 14, 2011
Posted by Carlos

Paginar una colección List

public List ListaPaginada(int pPagina, int pItemsPorPagina)
{          
   return ColFiltrada.Skip((pPagina - 1) * pItemsPorPagina).Take(pItemsPorPagina).ToList();
}
viernes, junio 10, 2011
Posted by Carlos
Tag :

Como amo a mi mamá

 7 años: ¡¡¡Mami Te Amo!!! 
10 años: ¡¡¡Mamá Te Quiero!!! 
15 años: ¿Ma ...má? 
17 años:¡¡¡Cómo jodes vieja!!!
20 años: ¡¡¡Quiero irme de esta casa!!! 
35 años: ¡¡¡Quiero volver con mamá!!! 
50 años: No te vayas viejita... 
70 años: ¡¡¡Cuanto daría por cinco minutos con mi mamá!!! 
viernes, junio 03, 2011
Posted by Carlos
Tag :

Utilizando generics para hacer un DeepCopy

Para hacer una copia de un objeto y tengamos dos objetos independientes, se requiere un DeepCopy:
public static class DeepCopier
    {
        /// Se usa un tipo generic para poder copiar cualquier objeto
        public static T Copy(T pItem)        {
            BinaryFormatter vFormatter = new BinaryFormatter();
            MemoryStream vStream = new MemoryStream();
            vFormatter.Serialize(vStream, pItem);
            vStream.Seek(0, SeekOrigin.Begin);
            T vResult = (T)vFormatter.Deserialize(vStream);
            vStream.Close();
            return vResult;
        }
    }

Para utilizarlo:

 /// Copiamos el objeto por si se va a cancelar
cGrid vObjCancel = DeepCopier.Copy(ConfigReporto);
miércoles, junio 01, 2011
Posted by Carlos

Populares!

- Copyright © - Oubliette - -Metrominimalist- Powered by Blogger - Designed by Johanes Djogan -