viernes, 31 de agosto de 2012

Metaetiqueta description en Blogger

La

metaetiqueta description

proporciona una descripción breve de la página que puede utilizarse como parte del texto que aparece en los resultados de la búsqueda; facilita al motor de búsqueda información sobre el sitio en el que se encuentra.

No está muy claro si la

metaetiqueta description

influye demasiado para

posicionar (SEO)

una web, al menos así lo comenta

Matt Cutts

(Google Software Engeneer) en este video. No sucede lo mismo con la

metaetiqueta keywords

que no la tiene en cuenta Google para el

posicionamiento

(aunque puede que sí otros buscadores) debido al abuso que se ha hecho de ella durante mucho tiempo.



También podéis encontrar más información al respecto en el siguiente link del blog de Google para webmasters.

Parece ser entonces que poca o ninguna influencia tendrá la

metaetiqueta description

en cuanto a

posicionamiento

, por supuesto menos que otros factores como la

etiqueta Title

, la

etiqueta H1

, la antigüedad o autoridad del dominio,... Deberíamos pensar en el usuario al redactar el contenido de la

metaetiqueta description

, al fin y al cabo el texto puede aparecer en bajo el título en los resultados de la búsqueda y debe "seducirle" para que pulse sobre nuestro enlace y no otro.

Bien, tras la introducción anterior para ponernos en situación os indicaré como rellenar la

metaetiqueta description

con diferente texto para cada una de las entradas de blog de

Blogger

. Los pasos serían los siguientes, es muy sencillo:
  1. Entramos en

    Blogger

    , vamos al apartado "Configuración - Preferencias de búsqueda" y habilitamos la descripción de búsqueda. En el bloque que nos aparece podemos hacer una breve descripción de nuestro blog.


  2. Editamos la entrada en la que queremos informar la

    metaetiqueta description

    , a la derecha de la pantalla veremos un nuevo campo "Descripción de búsqueda" en la que introduciremos la descripción deseada.


  3. Por último comprobamos que ha funcionado correctamente. Tras publicar la entrada, abrimos en el navegador la entrada correspondiente y visualizamos el código fuente de la página, podemos ver cómo aparece la

    metaetiqueta description

    .


Espero que os sea útil este artículo, dentro de

areaTIC

puedes encontrar otros artículos interesantes, no dudes en consultar nuestro archivo.


LECTURAS RELACIONADAS RECOMENDADAS POR AREATIC.NET

viernes, 24 de agosto de 2012

Manual SEO, 5 conceptos básicos

SEO (Search Engine Optimization, optimización para buscadores) consiste en una serie de técnicas que permiten posicionar una web en los primeros resultados de los buscadores, es lo que se conoce como posicionamiento orgánico o natural. Importante no confundir con SEM (Search Engine Marketing) que se refiere a la gestión eficaz de los enlaces patrocinados en los buscadores; en el año 2000 Google lanzó AdWords como herramienta SEM.

En este breve manual os indico 5 conceptos básicos para cualquier usuario que quiera introducirse en el mundo SEO:
  1. SEO on page es todo lo que podemos hacer dentro de una web para posicionarla mejor en los resultados de los buscadores. En este sentido es muy importante:

    • Los contenidos ofrecidos, si no hay contenidos interesantes no conseguiremos atraer visitas, ¿quién compra un libro en blanco, con 5 hojas o sin ningún interés? Siempre habrá alguien pero no llegará muy lejos dicho libro.
    • La lista palabras clave (keywords) que definen nuestro sitio y que los potenciales visitantes escriben en los buscadores.
    • Es necesario una web indexable, es decir, que pueda ser encontrada por los buscadores y donde sea accesible todo el contenido de todas las páginas que la forman; de esta manera los buscadores pueden clasificar los contenidos según corresponda. Contenidos flash e imágenes hacen webs muy visuales y atractivas pero los buscadores sólo son capaces de buscar en el texto de una web, nunca dentro de un flash ni una imagen.

  2. SEO off page es todo aquello externo a una web y que también sirve para conseguir una mejor posición en los resultados de los buscadores. Links desde otras webs, presencia en redes sociales... mejorarán el SEO off page de una web.

  3. Cuidado con algunas técnicas para mejorar el SEO on/off page, Google las penaliza y puede retirar una web de los resultados de búsqueda. Esto pasa y ha pasado a grandes marcas como BMW o Ricoh. Algunos de los temas que penalizan:

    • intercambio de links a gran escala (tú me linkas yo te linko)
    • tener links rotos
    • duplicar contenidos
    • tener más publicidad que contenido
    • utilizar múltiples tags H1
    • ...

  4. Eyetracking (seguimiento de ojos) es un proceso que evalua donde se fija la mirada. Si lo aplicamos a los resultados de búsqueda de Google podemos ver donde el usuario fija la vista al navegar.


    Comprobamos los 2 primeros resultados, acaparan la principal atención del usuario; bastante menos el tercero, menos el cuarto y prácticamente nada el resto... ni hablar de la segunda página... por tanto, es importante situar la web en los primeros resultados de la búsqueda. Se habla que el % de visitas según la posición en los resultados vendría a ser algo así como:

    • 1 resultado 42%
    • 2 resultado 12%
    • 3 resultado 9%
    • 4 resultado 6%
    • ...

    Es fácil pensar que las ventas de una web dependen del número de visitas que tengamos... pasar del 3er al 1er puesto en los resultados de la búsqueda multiplicaría por 4 nuestras visitas y por tanto nuestros ingresos.

  5. Pagerank es un valor numérico (de 0 al 10) que indica la importancia de una web para Google. Por ejemplo. www.google.com tiene un Pagerank de 9/10 pero www.google.es tiene un pagerank de 7/10. Puedes comprobar el Pagerank de la web que quieras con la siguiente utilidad:

    Comprueba el Pagerank:

    Algunos temas importantes sobre el Pagerank:

    • Tener un Pagerank alto en una web servirá para que esta web salga mejor posicionada en los resultados de las búsquedas.
    • Algunos podréis decir que el Pagerank es un valor asignado por Google pero existen otros buscadores... cierto, pero es importante considerar la cuota de mercado de Google (España, Francia, Alemania está en torno al 90%, 91% en Reino Unido...); en estos momentos es recomendable centrar esfuerzos en posicionar una web en Google frente a Yahoo, Bing u otros. En cualquier caso 3 aspectos a tener en cuenta:
      • Es importante ver a qué público va destinada nuestra web y posicionarla en los buscadores que utilice dicho público, por ejemplo, Baidu tiene la mayor cuota de mercado en China por lo que si nuestra web va dirigida a ese mercado deberemos posicionarnos en ese buscador.
      • Lo habitual es analizar el mercado al que se dirige nuestra web y posicionarnos en los 3-4 principales buscadores de ese mercado.
      • El efecto multiplicador de los buscadores. Hay buscadores que utilizan motores de otros en sus búsquedas, por ejemplo, si realizas una búsqueda en yahoo.es al final de los resultados aparece un bonito "Powered by Bing", posicinándote en Bing estarás también posicianado en Yahoo.
    • El Pagerank no se recalcula constantemente, es un proceso que se realiza varias veces al año y tarda varios días en completarse... por ejemplo en 2012 y a día de hoy se han realizado 2 actualizaciones, la primera semana de febrero y la primera de mayo.

Espero que os haya resultado interesante este primer artículo de SEO, en breve añadiremos más en el blog. Dentro de areaTIC puedes encontrar otros artículos interesantes, no dudes en consultar nuestro archivo.


LECTURAS RELACIONADAS RECOMENDADAS POR AREATIC.NET

viernes, 17 de agosto de 2012

C# Multithreading, Ejemplo IAsyncResult Pattern - BeginInvoke/EndInvoke

Hace años los sistemas operativos sólo soportaban un hilo de ejecución, en el momento en que evolucionaron hacía el Multithreading se abrió una vía de posibilidades muy interesante a los desarrolladores de cara a optimizar sus aplicaciones.

Existen varias posibilidades en C# para hacer que nuestras aplicaciones sean Multithreading.
  • Usar el espacio de nombres System.Threading: Tal vez esta sea la técnica más compleja ya que requiere conocer los conceptos STAT/MTAT para asegurar una gestión "ThreadSafe" de los hilos y entender como actua el contexto de sincronización para intercambiar información entre hilos.

  • IAsyncResult Pattern: Es un patrón que a partir de delegados permite invocar un método en segundo plano y recibir información cuando este termine su ejecución. A priori la gestión de los Threads resulta más sencilla que en el caso anterior. Veremos un ejemplo en este artículo.

  • BackGroundWorker: Microsoft recomienda el uso de este componente en nuestras aplicaciones Windows Forms siempre y cuando nuestros procesos necesiten interactuar con controles de la UI.

En este ejemplo veremos IAsyncResult Pattern, más adelante intentaremos publicar ejemplos sobre una gestión Multi-hilo con el resto de técnicas mencionadas en la sección Multithreading de areaTic.

Los métodos BeginInvoke() y EndInvoke() que se usan en el ejemplo, están disponibles vía CLR (Common Language Runtime) en todos los objetos que se usen en el espacio de nombres Windows.Forms. Tened en cuenta que si estamos programando en C# desde un ámbito diferente a Visual Studio es posible que IntelliSense del IDE no muestre referencia de estos métodos.

Vamos ya al ejemplo, crearemos un proyecto de tipo Aplicación de Consola desde Visual Studio en el que por defecto se incluirá la clase Program.cs con el método Main().

A continuación añadimos una clase Proceso.cs al proyecto la cual contendrá tres funciones que simularán realizar acciones que duran un tiempo determinado en cada caso.

namespace ThreadSamples
{
    public delegate string ProcesoNegocio(string pEntrada);

    public class Proceso
    {
        public string ProcesoNegocio1(string pEntrada)
        {
            //dormimos ejecución durante 7 segundos 
            //simulando una acción que tarda ese tiempo.
            System.Threading.Thread.Sleep(7000);
            //devolvemos fecha fin proceso concatenada a la fecha de entrada
            return string.Format("Fin Proceso 1: {0}-{1}", pEntrada, DateTime.Now.ToString());
        }

        public string ProcesoNegocio2(string pEntrada)
        {
            //dormimos ejecución durante 10 segundos 
            //simulando una acción que tarda ese tiempo.
            System.Threading.Thread.Sleep(10000);
            //devolvemos fecha fin proceso concatenada a la fecha de entrada
            return string.Format("Fin Proceso 2: {0}-{1}", pEntrada, DateTime.Now.ToString());
        }

        public string ProcesoNegocio3(string pEntrada)
        {
            //dormimos ejecución durante 3 segundos 
            //simulando una acción que tarda ese tiempo.
            System.Threading.Thread.Sleep(3000);
            //devolvemos fecha fin proceso concatenada a la fecha de entrada
            return string.Format("Fin Proceso 3: {0}-{1}", pEntrada, DateTime.Now.ToString());
        }
    }
}
Necesitaremos un delegado para cada método que tengamos intención de invocar asíncronamente. En este caso coincide el tipo de parámetro de entrada y salida de los 3 métodos por lo que nos valdría si creamos un sólo delegado.
namespace ThreadSamples
{
    public delegate string ProcesoNegocio(string pEntrada);
}

Crearemos también una clase ThreadSample.cs que nos facilitará la gestión del asíncrono y evitará que tengamos que programar en la clase principal Main.cs.



A continuación veremos como aplicar el patrón en la clase ThreadSample.cs, es importante fijarnos en el método IniciarProcesos y EndProceso.
  • IniciarProcesos: Se encarga de invocar las 3 funciones en Threads diferentes.

  • EndProceso: Se encarga de recibir las respuestas a medida que terminen su ejecución e informa en la consola de la aplicación sobre el fin de cada proceso.

En el ejemplo nos disponemos a ejecutar los 3 métodos desde la clase Main() pero abriendo un hilo diferente para cada método. Sin gestión Multithreading nuestra aplicación esperaría la respuesta del primer método para invocar al segundo y así sucesivamente. En este caso veréis que al implementar el patrón IAsyncResult cada método se invoca en un Thread diferente y al finalizar la ejecución cada Thread se comunica con el hilo principal para avisar que ha terminado la ejecución y es en este momento donde podemos recuperar los parámetros de salida de la función que hemos llamado asíncronamente.

A continuación veremos la implementación de la clase ThreadSample y como se usan los métodos BeginInvoke() y EndInvoke().

namespace ThreadSamples
{
    public class ThreadSample
    {
        ProcesoNegocio mProceso1;
        ProcesoNegocio mProceso2;
        ProcesoNegocio mProceso3;

        public ThreadSample()
        {
            //clase que contiene las 3 funciones que invocaremos
            Proceso Procesos = new Proceso();

            //definimos un delegado para gestionar cada una de las 3 llamadas asíncronas
            mProceso1 = new ProcesoNegocio(Procesos.ProcesoNegocio1);
            mProceso2 = new ProcesoNegocio(Procesos.ProcesoNegocio2);
            mProceso3 = new ProcesoNegocio(Procesos.ProcesoNegocio3);
        }

        public void IniciarProcesos()
        {
            //definimos un callBackObject que apunte al método EndProceso.
            AsyncCallback callback = new AsyncCallback(EndProceso);

            mProceso1.BeginInvoke(DateTime.Now.ToString(), callback, null);
            mProceso2.BeginInvoke(DateTime.Now.ToString(), callback, null);
            mProceso3.BeginInvoke(DateTime.Now.ToString(), callback, null);

            Console.Read();
        }

        public void EndProceso(IAsyncResult pReturn) 
        {
            string sReturn = "";
            //"casteamos" el objeto para tener un poco más de información y saber el método original del cual procede el CallBack
            //debido a que hemos "aprovechado" el mismo delegado para EndProceso.
            System.Runtime.Remoting.Messaging.AsyncResult pExtendedReturn = (System.Runtime.Remoting.Messaging.AsyncResult)pReturn;
            System.Delegate delegateInfo = (System.Delegate)pExtendedReturn.AsyncDelegate;
            //en función del método original llamamos al EndInvoke del delegado correspondiente para obtener la respuesta.
            switch (delegateInfo.Method.ToString()) 
            {
                case "System.String ProcesoNegocio1(System.String)":
                    sReturn = mProceso1.EndInvoke(pReturn);
                    break;

                case "System.String ProcesoNegocio2(System.String)":
                    sReturn = mProceso2.EndInvoke(pReturn);
                    break;

                case "System.String ProcesoNegocio3(System.String)":
                    sReturn = mProceso3.EndInvoke(pReturn);
                    break;
            }

            Console.WriteLine(sReturn);
        }
    }
}
En el constructor de la clase declaramos tres instancias del delegado ProcesoNegocio que apunten a los 3 métodos públicos de la clase Proceso.

El método IniciarProcesos() se encarga de definir un delegado de respuesta y hacer la llamada asíncrona a los 3 métodos. BeginInvoke espera tantos parámetros de entrada como hayan definidos en el delegado, en este caso tenemos tan solo un paramétro string de entrada. A parte de tantos parámetros de entrada como hayan definidos en el delegado, BeginInvoke permite pasarle un CallBackObject con firma void MethodName(IAsyncResult), a través del cual podemos indicarle el método de respuesta que ha de invocar una vez finalice la ejecución del proceso.

En cuanto a EndProceso, su función reside en llamar a delegado.EndInvoke() pasando el IAsyncResult que recibimos como entrada del método y ya veréis que el mismo método EndInvoke devuelve un tipo de datos igual que el que hayamos definido en nuestro delegado original.

Por último desde la clase Main() instanciamos ThreadSample y llamamos a IniciarProcesos(), el resultado será el siguiente:



Se puede ver en la imagen que nuestra aplicación no espera a finalizar proceso1 para ejecutar proceso2 si no que ejecuta cada uno en un Thread diferente y posteriormente gestiona las respuestas desde el hilo principal.

Resumiendo, es importante entender a nivel conceptual la secuencia de pasos que hemos seguido para implementar el patrón:
  • Instanciamos delegado D

  • Llamamos a D.BeginInvoke(Parametros Entrada + CallBackObject).

  • D ejecuta el método asociado y al finalizar llamará automaticamente a CallBackObject (método delegado respuesta).

  • Llamamos a D.EndInvoke(IAsyncResult) pasándole el IAsyncResult para recibir de vuelta los parámetros de salida del método que hemos invocado asíncronamente.
Gracias a esta técnica podemos agilizar procesos aprovechando toda la potencia del CPU que ejecuta la aplicación y evitar saturar el hilo principal con procesos pesados de negocio sin demasiada dificultad, sólo requiere dominar el uso de delegados en C#.

En caso que os dispongáis a implementar una gestión multi-hilo en una aplicación de tipo Windows.Forms / WPF y los hilos secundarios necesiten interactuar con elementos de la UI, aseguraos previamente que conocéis los requisitos para implementar una gestión ThreadSafe en Windows y así evitar problemas como el que se mencionaba en este artículo areaTIC: Error STATThreadAttribute

Espero os haya resultado útil el post, no olvidéis consultar el archivo de areaTIC tal vez hayan otros artículos que puedan interesarte!


viernes, 10 de agosto de 2012

El subproceso actual debe establecerse en modo de subprocesamiento controlado simple (Single Thread Apartment, STA) para poder realizar llamadas OLE. Asegúrese de que la función Main tienen marcado STATThreadAttribute. Esta excepción solo se desencadena si se adjunta un depurador al proceso.

Estamos desarrollando una aplicación Windows Forms sobre Framework 4.0 (también aplicable en versiones anteriores) y nos encontramos el siguiente error cuando nuestro código interactua con algún tipo de objeto OLE, por ejemplo componentes de la UI de Windows.Forms como Form, ListBox, UserControl, DialogBox, etc ...
El subproceso actual debe establecerse en modo de subprocesamiento controlado simple (Single Thread Apartment, STA) para poder realizar llamadas OLE. Asegúrese de que la función Main tienen marcado STATThreadAttribute. Esta excepción solo se desencadena si se adjunta un depurador al proceso. 
El error nos indica que estamos realizando alguna operación no permitida entre Threads. Posiblemente si hemos llegado a este punto es porque por algún motivo nos interesa que nuestra aplicación tenga más de un hilo de ejecución al realizar determinadas acciones.

Remarcar que en función de como tengamos configurado Visual Studio, podríamos llegar a recibir un error diferente al del título de la entrada.
Operación no válida a través de subprocesos: Se tuvo acceso al control 'xxx' desde un subproceso distinto a aquel en que lo creó.
Si creamos un nuevo proyecto de tipo Aplicación de Windows Forms desde Visual Studio, veremos que por defecto incorpora un formulario Form1.cs y la clase Program.cs que contiene un método Main.
namespace ThreadSamples
{
    static class Program
    {
        /// <summary>
        /// Punto de entrada principal para la aplicación.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
Es importante fijarnos en el atributo STAThread del método Main. En caso que nuestra aplicación no tenga este atributo seguramente ese sea el origen del problema. Es imposible explicar a fondo como Windows y .NET se comportan con objetos COM en un solo artículo de modo conciso, me quedaría con el concepto de que nuestra aplicación windows necesita definir un hilo principal en el single-thread apartment (STA) y por tanto el primer formulario que se muestre en nuestra aplicación debe lanzarse desde un método marcado con el atributo STAThread.

Si salvado este primer caso seguimos teniendo problemas problablemente la causa sea que hayamos ejecutado procesos en background una vez lanzado el formulario principal y alguno de estos procesos intenta interactuar con algún control de la UI que no ha sido creado desde el mismo hilo de ejecución en el que se está ejecutando el proceso.

Vamos a reproducir el problema con un ejemplo sencillo.
  • Thread Principal (P) -> Se encarga de lanzar el formulario principal que contiene un elemento TextBox y un Button.

  • Thread Secundario (S) -> Realiza un proceso que se lanza al pulsar el Button de nuestro formulario y al finalizar modifica el valor del TextBox para indicar la fecha exacta en que ha acabado el proceso.


El siguiente código nos servirá como base para reproducir el error y posteriormente ver como solucionarlo:
namespace ThreadSamples
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //creamos nuevo hilo de ejecución para lanzar el método Proceso
            Thread procesoBackGround = new Thread(new ThreadStart(Proceso));
            procesoBackGround.Start();
        }

        private void Proceso() 
        { 
            //simulamos proceso parando ejecución 5 segundos...
            Thread.Sleep(5000);
            //actualizamos fecha en que finaliza la ejecución del proceso.
            textBox1.Text = DateTime.Now.ToString();
        }
    }
}
Al ejecutar y pulsar el botón, en el momento en que la aplicación se dispone a modificar la propiedad Text de la caja de texto, se genera una excepción.
Operación no válida a través de subprocesos: Se tuvo acceso al control 'textBox1' desde un subproceso distinto a aquel en que lo creó.
Veamos como implementar código ThreadSafe que evitará el problema, necesitaremos hacer los siguiente ajustes en el código:

  • Crear un método privado en Form1 que se encargará de interactuar con el TextBox.
    private void InteractuarUI(string pFechaFinProceso) 
    {
      textBox1.Text = pFechaFinProceso;
    }
    
  • Crear un delegado con los mismos parámetros de entrada y salida del método que acabamos de crear.
    public delegate void FinProceso(string pValue);
    
  • Cambiar la línea del método Form1.Proceso() en la que asignamos valor a textbox1.Text por el siguiente fragmento de código.
    this.Invoke(new FinProceso(InteractuarUI),DateTime.Now.ToString());
    

Con esto ya tendríamos una implementación ThreadSafe de nuestro proceso y no debería generarse ninguna excepción. El método Invoke() está implicito en todo los controles que heredan de Windows.Forms y garantiza que .NET se encargará mediante el contexto de sincronización que el intercambio de información entre los hilos es seguro. Básicamente lo que hace .NET es asegurarse que el trabajo "conflictivo" lo hará el Thread que corresponda, en este caso (P).

Existen otras técnicas para solucionar el problema que a priori resultan más complejas pero a su vez permiten controlar más aspectos del comportamiento MultiThreading.
  • En la versiones más recientes del Framework, .NET distribuye la clase SynchronizationContext a partir de la cual podríamos intercambiar información entre diferentes hilos de modo seguro.

  • Existe el componente BackGroundWorker disponible en aplicaciones Windows Forms que permite gestionar la comunicación entre procesos en segundo plano, recomendado especialmente si estos han de interactuar con la UI.

Hasta aquí el artículo, espero os resulte útil. No olvidéis consultar el archivo de areaTIC hay artículos que podrían interesarte!


domingo, 5 de agosto de 2012

Error #-2147467259 : [Microsoft][Administrador de controladores ODBC] No se encuentra el nombre del origen de datos y no se especificó ningún controlador predeterminado

Nos disponemos a publicar un sitio web usando IIS 7.0 / 7.5 en un Windows 2008 Server R2 64 bits y en algún punto de la aplicación se usan conexiones ODBC para el acceso a datos. Al ejecutar la aplicación recibimos el siguiente error:
Error #-2147467259 :  [Microsoft][Administrador de controladores ODBC]  No se encuentra el nombre del origen de datos y no se especificó ningún controlador predeterminado
El error se produce cuando el sistema operativo busca mediante el Administrador de controladores ODBC un origen de datos y no lo encuentra. Si no hemos cambiado ninguna característica del grupo de aplicaciones por defecto nuestro site buscará el origen de datos en ámbito 64 bits.

Si este es nuestro caso simplemente deberíamos asegurarnos que el ODBC al que se hace referencia en nuestro site esté correctamente creado desde el Administrador de orígenes de datos del sistema operativo al cual podemos acceder desde Herramientas Administrativas.


En caso que el problema persista deberíamos revisar la característica Habilitar aplicaciones de 32 bits del Grupo de Aplicaciones al que está asociado el site en IIS. Por defecto al crear un Grupo de Aplicaciones no está activada pero podría ser que por algún motivo haya surgido la necesidad de hacerlo, aquí en areaTIC vimos hace poco un ejemplo El componente ActiveX no puede crear el objeto.

Para solucionar el problema tenemos dos opciones:
  • En caso que no necesitemos que nuestra aplicación sea compatible 32 bits podríamos crear un nuevo Grupo de Aplicaciones y acto seguido asociar nuestro site.

  • Si nuestra aplicación ha de ser compatible con aplicaciones 32 bits deberíamos crear los ODBC en ámbito 32 bits desde el Administrador de orígenes de datos 32 bits que hayaremos en la ruta %SystemRoot%\SysWOW64\odbcad32.exe del servidor.

Para más información recomendamos visitar las páginas de soporte de microsoft. Nombres de origen de datos y sistemas operativos de 64 bits

No olvides consultar el archivo de areaTIC, puedes encontrar otros artículos interesantes!


LECTURAS RELACIONADAS RECOMENDADAS POR AREATIC.NET

miércoles, 1 de agosto de 2012

C# Serializar XML con retorno de carro entre tags, XmlSerializer, XmlWriter Indent

Nos disponemos a serializar un objeto a formato XML en disco usando la combinación de clases System.Xml.Serialization.XmlSerializer y System.Xml.XmlWriter. Por defecto XmlWriter no añade retornos de carro en el fichero de texto plano resultante, si lo abrimos con un bloc de notas una vez serializado en disco veremos algo así:
<xml><tag1>1</tag1><tag2>2</tag2></xml>
Tal vez, nos interese que el resultado tenga este formato:
<xml>
<tag1>1</tag1>
<tag2>2</tag2>
</xml>
Esta característica se conoce como Indentación del contenido y XmlSerializer, XmlWriter nos permiten controlarlo del siguiente modo:
ObjetoSerializable obj = new ObjetoSerializable();
//... (Completar valores)

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = "\r";

using (XmlWriter oWriter = XmlWriter.Create(string.Format(@"c:\{0}",nombreFichero),settings))
{
  XmlSerializer oSerializer;
  oSerializer = new XmlSerializer(typeof(ObjetoSerializable));
  oSerializer.Serialize(oWriter, obj);
}
En el archivo de areaTIC puedes encontrar otros artículos interesantes, no dudes en consultarlo.