viernes, 15 de abril de 2011

Crear una sección personalizada en Umbraco (I)

seccion_umbraco

Una de las cosas que más me ha sorprendido de este CMS es la cierta facilidad para crear nuevas secciones y ser incorporadas al panel de administración.

Con estas breves instrucciones que veremos a continuación vamos a tunear, tunear en todas sus reglas y además de forma oficial con nuevas características que nos permitirán poner nuestro CMS al doscientos por ciento.

Empezamos por la base de datos

Empezaremos por localizar las siguientes tablas en la nueva base de datos generada en la instalación de Umbraco.
  • umbracoApp, en esta tabla se almacén todas las secciones que se encuentran disponibles.
  • umbracoAppTree, aquí especificamos los datos del nuevo nodo como el nombre de la librería o la clase de inicialización.
  • umbracoUser2app, aquí definimos los permisos para la nueva sección.

 

Tabla UmbracoApp

  • sortOrder: indica el orden en el que aparecerá en la interfaz dentro del módulo secciones.
  • appAlias: simplemente un nombre identificativo, vaya el identificador.
  • appIcon: la clase CSS que representa al icono, ahora lo vemos.
  • appName: esto es un nombre descriptivo pero no prestéis atención porque el nombre definitivo será ajustado mediante archivos de configuración regional, ahora lo vemos.
  • appInitWithTreeAlias: valor NULL.

Tabla UmbracoAppTree

  • treeSilent: ponemos False.
  • treeInitialize: ponemos True.
  • treeSortOrder: ponemos un cero, será el primer elemento.
  • appAlias: el mismo de antes.
  • treeAlias: el mismo valor que appAlias.
  • treeTitle: el mismo valor que appAlias.
  • treeIconClosed: ponemos .sprTreeFolder.
  • treeIconOpen: ponemos .sprTreeFolder_o.
  • treeHandlerAssembly: este campo representa el nombre del ensamblado que contiene la clase para iniciar la nueva sección, por ejemplo si la libreria resultante es “holamundo.dll” pondríamos “holamundo”, obviando la extensión.
  • treeHandlerType: el nombre de la clase que contiene los métodos que ejecutarán la carga del árbol de la nueva sección, ahora lo vemos.
  • action: valor NULL.

Tabla UmbracoUser2app

En esta tabla es donde damos los permisos al usuario administrador para que acceda a la nueva sección.

  • user: ponemos un cero.
  • app: ponemos el mismo valor que appAlias

miércoles, 13 de abril de 2011

Primer acercamiento a Umbraco

logo_umbraco

 

Instalación

Tan solo comentar que podéis realizar la instalación desde Web Platform Installer, será todo mucho más rápido y transparente con la excepción de indicar que la instalación se realice como un nuevo sitio web, me encontré problemas intentándolo instalar como directorio virtual.

También podéis acceder a http://umbraco.com/ donde encontrar bastante información y documentación de partida, sobre todo muy interesante la sección de videos.

Personalizando el splash de login

Para acceder al área de administración escribimos la siguiente ruta: http://host/umbraco/login.aspx,

Tenemos que editar y modificar los siguientes recursos gráficos para adaptarlos a la identidad de nuestro sitio web. Para ello simplemente lo abrimos con nuestro editor gráfico preferido y actualizamos los siguientes recursos:

/umbraco/images/loginbg.gif
/umbraco/images/loginbg.png
/umbraco/images/umbracosplash.gif
/umbraco/images/umbracosplash.png

Para modificar el texto de la pantalla de login localizamos el archivo:

/umbraco/config/lang/es.xml

y buscamos la entrada “topText” y “bottomText” para modificar el texto de la pantalla de login, podría ser algo parecido a esto:

<key alias="topText"><![CDATA[Bienvenido a www.midominio.com, escribe tu nombre de usuario y clave en los campos de debajo:]]></key>

<key alias="bottomText"><![CDATA[<p style="text-align:right;">&copy; 2001 - %0% <br /><a href=http://www.midominio.com style="text-decoration: none" target="_blank">www.midominio.com</a></p> ]]></key>

Con estos sencillos pasos tendréis vuestra pantalla de acceso a CMS Umbraco personalizado y a vuestro gusto.

domingo, 10 de abril de 2011

Perdón, me he equivocado…

error

¿Porqué cuando llega el jefe de una reunión con el cliente o de una visita, lo primero que dice es?: “señores tenemos una oportunidad y es de vital importancia para la empresa”.

El empleado piensa que será otra patata caliente y lo realmente importante es otro objetivo….comenta al compañero ”y esto de que va ahora, ¿en este momento?, ¿no está viendo que no nos lleva a ningún lado el hacerlo de esta manera?, si lo que estaba haciendo es realmente lo que tenía que hacer!!!”.

¿Os suena?, seguro que nos ha pasado en alguna ocasión, y si esto ocurre es que algo en el sistema no funciona, por varios factores.

¿Me he sabido comunicar de la manera correcta?
¿He hablado en el momento adecuado?
¿He expresado con claridad mi punto de vista?
¿He aceptado mis errores e intentado corregirlos?
¿Tenéis oportunidad de preguntar el porqué de las decisiones?
¿He preguntado el porqué de una decisión cuando he tenido oportunidad?
¿Habéis puesto el freno antes de llegar al callejón sin salida, aún sabiendo que no la tenía?
¿Somos conscientes del dinamismo de las necesidades?
¿Sois conscientes de la seguridad virtual en la que vive un empleado?
¿Tendría que haber dicho NO en alguna ocasión?

Tras varias victorias y derrotas a lo largo de mi trayectoria profesional, hoy he vuelto a equivocarme, pero levanto la cabeza y lo digo a lo dos punto cero, sí, me he equivocado, seguramente mañana volveré a hacer las mismas cosas pero os aseguro que de manera distinta.

Después de un largo fin de semana de reflexión, todavía no soy consciente de las cosas que he hecho mal pero lo que si esta claro es que por las razones que sean no estoy cumpliendo los objetivos que me marqué hace unos meses, así que ahora toca seguir reflexionando, recapacitar, echar leña al fuego, ponerse las pilas y corregir el rumbo.

miércoles, 6 de abril de 2011

SEO rápido, posiciona tu web con ASP.NET + IIS 7

 

Si quieres mejorar la visibilidad de tu página web y competir con el resto del mercado puedes seguir estas pequeñas pautas realizando un mínimo esfuerzo en el desarrollo y publicación de tu sitio web, la creación de estos pasos no te llevará más de 20 minutos.

Calidad del contenido

Esto es fundamental y estamos ya hartos de escucharlo pero si no ofrecemos algo de interés y calidad al usuario, ten claro que no volverá a nuestra web y pasará a convertirse en visitante Kleenex.

Semántica del contenido

Esto si que nos cuesta poco trabajo y veo cada regalito todos los días que a veces se me ponen los pelos de punta. Si queremos indicar que el texto es un título por favor usemos una etiqueta <h1>, y no usemos etiquetas para formatear y poner bonita nuestra web, del tipo….pongo un <br/><br/><br/> que hace falta para “respirar” según dice el “creativo”.

Título de las páginas y descripción

Ponle un titulo y descripción a cada una de tus páginas utilizando la siguiente etiquetas en tu documento html.

<meta name="description" content="Descripción corta de mi página, no más de 125 caracteres" />
<title>Título de mi página</title>

Uso de palabras claves

Utiliza la etiqueta keywords para añadir palabras o tags que permitan a los buscadores localizar los contenidos de tus páginas.

<meta name="keywords" content="coche, venta, segundamano" />

Inclusión de archivo sitemap.xml

Para la inclusión de nuestro archivo sitemap usaremos la herramienta on-line XML Sitemaps Generator, tan solo tenemos que indicar el sitio de nuestra web y el solito generará el archivito listo para copiar y pegar en el raíz de nuestra web. Tan solo echo en falta la etiqueta

<priority>0.65</priority> para cada uno de los nodos, es algo que podemos hacer para una segunda vuelta, esto nos permitirá de cada a los buscadores indicar que página es “más importante” dentro de nuestro sitio web, por ejemplo la home debería tener una prioridad más elevada que por ejemplo el aviso legal.

Inclusión de archivo robots.txt

Si por ejemplo queréis que cualquier robot de búsqueda o rastreador no cachee los contenidos de la carpeta imágenes o directorio upload, incluid estas líneas en un archivo llamado robots.txt y lo colgáis en el raíz del site.

User-Agent: *
Disallow: /imagenes/
Disallow: /upload/

Tuneando el web.config de nuestra web

Nos apoyaremos en la extensión URL Rewrite que debéis instalar en vuestro servidor, podeis utilizar la herramienta Web Platform Installer que ella se encargará solita de la instalación.

Antes de subir a producción vuestro sitio web debéis tunear un poco el web.config para aquellos que trabajéis con APS.NET Webforms, de manera que dentro del nodo system.webServer colocáis esto.

<rewrite>
  <rules>

    <rule name="CanonicalHostNameRule1">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTP_HOST}" pattern="^www\.midominio\.com$" negate="true" />
      </conditions>
    </rule>


    <rule name="LowerCaseRule1" stopProcessing="true">
      <match url="[A-Z]" ignoreCase="false" />
      <action type="Redirect" url="{ToLower:{URL}}" />
      <conditions>
        <add input="{URL}" matchType="Pattern" pattern="WebResource.axd" ignoreCase="true" negate="true" />
      </conditions>
    </rule>


    <rule name="Default Document URL Rewrite" stopProcessing="true">
      <match url="(.*?)/?Default\.aspx$" />
      <action type="Redirect" url="{R:1}/" />
    </rule>

 Si por ejemplo tenéis una página del tipo http://www.midominio.com/avisolegal.aspx y queréis convertirla a http://www.midominio.com/aviso-legal incluir las siguientes reglas, una por cada página aspx que tengáis en vuestro proyecto  

<rule name="RedirectUserFriendlyURL1" stopProcessing="true">
      <match url="^avisolegal\.aspx$" />
      <conditions>
        <add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
      </conditions>
      <action type="Redirect" url="aviso-legal" appendQueryString="false" />
    </rule>
    <rule name="RewriteUserFriendlyURL1" stopProcessing="true">
      <match url="^aviso-legal$" />
      <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
      <action type="Rewrite" url="avisolegal.aspx" />
    </rule>

        </rules>

Igualmente aplicamos las reglas de salida, para convertir http://www.midominio.com/aviso-legal en http://www.midominio.com/avisolegal.aspx y pueda ser interpretado por el framework.


      <outboundRules>
        <rule name="OutboundRewriteUserFriendlyURL1" preCondition="ResponseIsHtml1">
          <match filterByTags="A, Form, Img" pattern="^(.*)avisolegal\.aspx$" />
          <action type="Rewrite" value="{R:1}/aviso-legal" />
        </rule>

    <preConditions>
      <preCondition name="ResponseIsHtml1">
        <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
      </preCondition>
    </preConditions>
  </outboundRules>
</rewrite>

Dando a conocer nuestra web

Podéis visitar http://www.google.es/addurl/ y dar de alta la dirección electrónica de vuestro sitio web.

Además es interesante darnos de alta en http://www.dmoz.org/, repositorio común utilizado por muchos de los buscadores conocidos.

Con estos simples pasos, lograréis ganar presencia, calidad y posicionamiento a vuestra web, claro que existen muchos más técnicas y factores a tener en cuenta, pero puede ser un buen punto de partida para profundizar y realizar otra serie de mejoras que veremos en nuevos posts.

sábado, 1 de enero de 2011

Desarrollo orientado a productos

 

Network ServiceYa nadie puede discutir que el modelo SaaS como enfoque de modelo de negocio es una realidad cotidiana, donde normalmente existen grandes ventajas tanto para el cliente como el proveedor, pero…¿habéis hecho una pausa en el desarrollo de vuestro producto y considerado la posibilidad de convertirlo realmente en un servicio?.

Seguramente, la mayoría de vuestros desarrollos serán técnicamente de muy alto valor, pero de que nos sirve si todo ese potencial no es capaz de transmitirse y comunicarse con el resto de la comunidad 3.0, o incluso bajando el listón con otras aplicaciones de valor añadido.

Si después de trabajar meses en un producto redondo con una inteligencia de negocio fantástica no sois capaces de transmitirlo el fracaso estará en la primera línea de código, y vamos a explicarlo más claramente con un ejemplo.

Imaginaros a Albert Einstein formulando en su cabeza la teoría de la relatividad, y de repente decidiera no disponer de boca, mano u oídos, sería un desastre y una pena no conocer las posibilidades de este genio.

Pues a nuestro producto le puede ocurrir lo mismo si decidimos no escuchar la problemática real del usuario, es decir, si por ejemplo hemos trabajado en un fantástico CRM sería genial que pudiera exportar determinada información de contactos a un formato estándar para agregarlos o sincronizarlos con mi IPhone.

De igual manera si dispongo de unos contactos perfectamente organizados en mi Google Contacts, podría ofrecer la posibilidad de agregarlos a mi producto para enriquecerlo y darle un valor añadido apoyado por otras herramientas de mercado.

Espero vuestras opiniones que seguro serán interesantes.

lunes, 1 de noviembre de 2010

Reutilización de informes en entornos de aplicación orientadas a productos

 

Merece la pena escribir este post, ya que me ha dado algún que otro dolor de cabeza hasta llegar a la solución. Vamos a jugar un ratito a pasar como parámetro la cadena de conexión para visualizar un informe mediante Report Viewer 2010.

 

Generando el informe con Report Builder 3.0

Esta herramienta, ya mencionada en posts anteriores, nos permitirá crear la definición del informe y obtener un archivo en formato RDL (Report Definition Language) se trata de un fichero estándar XML que nos permite cotillear las tripas y ver lo que ocurre en la “sala de máquinas”.

Primeramente tendremos que incluir un nuevo parámetro en el informe al que llamaremos BaseDatos, lo marcaremos como oculto, guardamos y salimos de Report Builder.

 

Modificando el RDL

Partiendo de cualquier informe generado previamente con dicha herramienta, solo nos queda guardar el archivo (en el escritorio de Windows por ejemplo) y usar el bloc de notas para ver en detalle la definición del mismo. Tendremos que localizar al principio del documento la sección ConnectString del elemento DataSource y modificarlo de la siguiente manera:

<?xml version="1.0" encoding="utf-8"?>
<Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"xmlns:cl="http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition"xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition">
  <AutoRefresh>0</AutoRefresh>
  <DataSources>
    <DataSource Name="GIE">
      <ConnectionProperties>
        <DataProvider>SQL</DataProvider>
        <ConnectString>="Password=XXXX;Persist Security Info=True;User ID=XXXX;Data Source=XXXX;Initial Catalog=" &amp; Parameters!BaseDatos.Value</ConnectString>
      </ConnectionProperties>
      <rd:DataSourceID>2bf79f31-84cc-4a46-b53d-93fbf236f92d</rd:DataSourceID>
    </DataSource>
  </DataSources>

Lo que hemos modificado con respecto al original ha sido la inclusión de la expresión Parameters!BaseDatos.Value embebida en la cadena de conexión delDataSource

Os dejo un enlace de interés donde podréis indagar mas sobre estas cuestiones:http://msdn.microsoft.com/en-us/library/ms156450.aspx#Expressions

Hay otro punto importantísimo y que también me costo un buen rato, no se porque razón la definición del parámetro BaseDatos tiene que ser el primero de la colección, podemos observar también su definición en el propio documento RDL casi al final del archivo:

<ReportParameters>
  <ReportParameter Name="BaseDatos">
    <DataType>String</DataType>
    <Prompt>BaseDatos</Prompt>
    <Hidden>true</Hidden>
  </ReportParameter>
  <ReportParameter Name="IdUsuarioComercial">
    <DataType>Integer</DataType>
    <DefaultValue>
      <DataSetReference>
        <DataSetName>Comerciales</DataSetName>
        <ValueField>IdUsuario</ValueField>
      </DataSetReference>
    </DefaultValue>
    <Prompt>Comercial</Prompt>
    <ValidValues>
      <DataSetReference>
        <DataSetName>Comerciales</DataSetName>
        <ValueField>IdUsuario</ValueField>
        <LabelField>Comercial</LabelField>
      </DataSetReference>
    </ValidValues>
    <MultiValue>true</MultiValue>
  </ReportParameter>

 

Publicación del informe mediante Report Manager

Ya sabéis que Report Manager es la herramienta web que nos permite gestionar y publicar informes cuando nos basamos en RemoteMode, solo tendremos que asegurarnos de indicar que no se necesitan credenciales para la visualización del informe, os dejo la pantalla donde se parametriza:

report_manager

 

Report Viewer en Visual Studio

Os dejo el código a implementar desde Visual Studio con la llamada al informe:

if (!IsPostBack)
{
    ReportViewer1.ProcessingMode = ProcessingMode.Remote;
    ServerReport serverReport = ReportViewer1.ServerReport;
    serverReport.ReportServerUrl = new Uri(Properties.Settings.Default.ReportServer);
    serverReport.ReportPath = Request["ReportPath"].ToString();
    ReportParameter rp = new ReportParameter("BaseDatos",”XXXXX”);
    serverReport.SetParameters(rp);

}

Esto nos permitirá reutilizar informes que compartan diferentes bases de datos con misma estructura, imprescindible cuando se trata por ejemplo de desarrollo de aplicaciones orientadas a productos donde existe un único repositorio de ejecución de aplicación pero diferentes bases de datos (una para cada cliente).

Como inconveniente es que no podéis hacer ingeniería inversa, si abres el informe (ya modificado desde el bloc de notas anteriormente) mediante Report Manager al volverlo a publicar o grabar destroza la expresión de paso de parámetros de la cadena de conexión. Se lo comunicaremos a Redmond para que lo corrijan Guiño

viernes, 2 de julio de 2010

Comunicando Android y Web Services .NET

Android_NET

En esta ocasión el objetivo del post será el de comunicar dos tecnologías totalmente complementarias: Google Android yMicrosoft .NET, para ello nos basaremos en el protocolo SOAP, más concretamente en Web Services desde el lado Microsoft y la creación de un componente personalizado que permitirá consumir y acceder a los datos del modelo de negocio desde un dispositivo Android.

Estudiaremos los casos más sencillos para comunicar un servicio web y un dispositivo móvil, desde la interacción de datos simples hasta estructuras de datos complejas definidos por el desarrollador.

En el ejemplo que vamos a abordar el sistema comprobará un par usuario y contraseña y nos informará si el usuario en cuestión se encuentra registrado dentro del repositorio de members de nuestra aplicación. La arquitectura que entrará en juego será la siguiente, partiremos primeramente de un servicio web que será el encargado de albergar la lógica de comprobación y autenticación de usuario junto con un cliente, en este caso un dispositivo móvil que será el encargado de consumir dicho servicio e informar al usuario del resultado de la operación.

 

Definiendo el Web Services .NET

No profundizaremos demasiado en este aspecto puesto que no es el objetivo del post, partiremos de una clase de tipo “System.Web.Services.WebService” en la que incluiremos un método “EsUsuarioValido” que nos devolverá un objeto de tipo “Usuario” si la autenticación se ha realizado con éxito. Nos debería de quedar algo así:

[WebMethod]
public Usuario EsUsuarioValido(string username, string password)
{
    Usuario reply = null;

    using (Contexto ctx = new Contexto())
    {
        reply = new CADUsuario(ctx).ObtenerUsuario(username, password);
    }

    return reply;
}

La clase Usuario nos debería quedar algo así:

namespace WebService.Entidades
{
    public class Usuario
    {
        …

        private string username;

        public string Username
        {
            get { return username; }
            set { username = value; }
        }
        private string password;

        public string Password
        {
            get { return password; }
            set { password = value; }
        }

        …

    }
}

Ya solo nos quedaría realizar el despliegue y publicarlo en un sitio visible para ser consumido desde cualquier cliente. El siguiente paso que estudiaremos será el desarrollo de la capa del cliente, encargada de consumir y comunicarse con nuestro servicio web, en este caso el dispositivo móvil elegido es Android sobre la versión1.6 aunque también funcionaría en versiones superiores 2.2

 

Consumiendo el servicio web .NET desde Android

Para empezar sera necesario descargar el paquete ksoap2-android de la siguiente dirección: http://code.google.com/p/ksoap2-android/downloads/list, ya solo queda incluirlo en nuestra aplicación Android (http://developer.android.com/guide/index.html, si os queréis iniciar está bastante completa), en el caso de estar trabajando con el IDE Eclipse nos situamos con el botón derecho sobre las propiedades del proyecto y añadimos la referencia bajo la opción Java Build Path.

En la estructura de nuetro proyecto nos encontraremos dos clases, una de ellas será Usuario y otra a la que llamaremos Seguridad. La primera solo la utilizaremos como objeto de transporte de datos y la segunda será la encargada de manejar y contendrá los métodos propios de acceso a la autenticación, actuará de proxy en la comunicación con el servicio web.

Os dejo el ejemplo de la clase de datos Usuario, esto es una lata pero ya sabéis que hablamos de Java así que tendremos que picar algo más de código, Microsoft nos malacostumbra a hacerlo todo con el ratón:

package jcantos.demo.entidades;

import java.util.Hashtable;

import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class Usuario implements KvmSerializable {
    private int idUsuario;
    private String nombre;
    private String email;
    private String username;
    private String password;

    public Usuario(){
        PI_idUsuario.setName("IdUsuario");
        PI_nombre.setName("Nombre");
        PI_email.setName("Email");
        PI_username.setName("Username");
        PI_password.setName("Password");

        PI_idUsuario.setType(PropertyInfo.INTEGER_CLASS);
        PI_nombre.setType(PropertyInfo.STRING_CLASS);
        PI_email.setType(PropertyInfo.STRING_CLASS);
        PI_username.setType(PropertyInfo.STRING_CLASS);
        PI_password.setType(PropertyInfo.STRING_CLASS);
    }
    public void setIdUsuario(int idUsuario) {
        this.idUsuario = idUsuario;
    }

    public int getIdUsuario() {
        return idUsuario;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getNombre() {
        return nombre;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUsername() {
        return username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }
    private static PropertyInfo PI_idUsuario = new PropertyInfo();
    private static PropertyInfo PI_nombre = new PropertyInfo();
    private static PropertyInfo PI_email = new PropertyInfo();
    private static PropertyInfo PI_username = new PropertyInfo();
    private static PropertyInfo PI_password = new PropertyInfo();
    private static PropertyInfo[] PI_PROP_ARRAY =
    {
        PI_idUsuario,
        PI_nombre,
        PI_email,
        PI_username,
        PI_password
    };

    @Override
    public Object getProperty(int param) {
        Object object = null;
        switch(param)
        {
            case 0 : object = new Integer(idUsuario);break;
            case 1 : object = nombre;break;
            case 2 : object = email;break;
            case 3 : object = username;break;
            case 4 : object = password;break;
        }
        return object;    }

    @Override
    public int getPropertyCount() {
        return 5;
    }

    @Override
    public void getPropertyInfo(int param, Hashtable arg1, PropertyInfo propertyInfo) {
        switch(param){
            case 0:
                propertyInfo.type = PropertyInfo.INTEGER_CLASS;
                propertyInfo.name = "IdUsuario";
                break;          
            case 1:
                propertyInfo.type = PropertyInfo.STRING_CLASS;
                propertyInfo.name = "Nombre";
                break;          
            case 2:
                propertyInfo.type = PropertyInfo.STRING_CLASS;
                propertyInfo.name = "Email";
                break;          
            case 3:
                propertyInfo.type = PropertyInfo.STRING_CLASS;
                propertyInfo.name = "Username";
                break;          
            case 4:
                propertyInfo.type = PropertyInfo.STRING_CLASS;
                propertyInfo.name = "Password";
                break;          
        }
    }

    @Override
    public void setProperty(int param, Object obj) {
        switch(param)
        {
            case 0  : idUsuario     = ((Integer)obj).intValue(); break;
            case 1  : nombre     = (String)obj; break;
            case 2  : email     = (String)obj; break;
            case 3  : username     = (String)obj; break;
            case 4  : password     = (String)obj; break;
        }  
    }
}

Me parece algo tosco para indicar a una clase que es Serializable, en .NET simplemente marcaríamos como atributo [Serializable] pero bueno “eso es así”. Y ahora os dejo la clase correspondiente al consumo del web services.

package jcantos.demo.utiles;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.util.Log;
import jcantos.demo.entidades.*;

public class Seguridad {
    private static final String METHOD_NAME = "EsUsuarioValido";
    private static final String NAMESPACE = "
http://tempuri.org/";
    private static final String URL = "http://www.jcantos.net/webservice.asmx"; //sustituir esta URL por el sitio definitivo
    private static final String SOAP_ACTION = "
http://tempuri.org/EsUsuarioValido";

    private static Usuario usuario=null;
    public static Usuario EsUsuarioValido(String username, String password){
        Usuario reply=null;
        try {
             SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
             request.addProperty("username", username);
             request.addProperty("password", password);
             SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
             envelope.dotNet=true;
             envelope.setOutputSoapObject(request);
             HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
             androidHttpTransport.call(SOAP_ACTION, envelope);
             SoapObject result = (SoapObject)envelope.getResponse();
             if (result!=null){
                    reply=new Usuario();
                 reply.setIdUsuario(Integer.parseInt(result.getProperty("IdUsuario").toString()));
                 reply.setNombre(result.getProperty("Nombre").toString());
                 reply.setEmail(result.getProperty("Email").toString());
                 reply.setUsername(username);
                 reply.setPassword(password);
             }
         } catch (Exception e) {
             Log.e("Servicio_Web",e.getMessage());
         }
        return reply;
    }

    public static void setUsuario(Usuario usuario) {
        Seguridad.usuario = usuario;
    }

    public static Usuario getUsuario() {
        return usuario;
    }
    public static boolean EsLogueado(){
        return Seguridad.usuario!=null;
    }
}

Me parece un tema interesantísimo, imaginaros las posibilidades que se nos abre y el abanico de oportunidades para integrar vuestros cacharritos con aplicaciones ya desarrolladas, no solamente en .NET sino cualquier otro lenguaje JAVA por ejemplo,……¿quién nos quita que pudiésemos elaborar un servicio web a modo de gateway que expusiese aquellos métodos que quisieran ser consumidos por un dispositivo móvil?. Y no solo hablamos a modo de consulta, aquí os dejo un ejemplo en el que podemos actualizar la clave de un usuario una vez que la autenticación se ha realizado con exito, básado en el ejemplo anterior.

Editando y actualizando objetos de negocio desde el dispositivo móvil

Supongamos que un usuario ha realizado una operación de login con éxito y desea cambiar o actualizar su perfil, informando al sistema central del cambio de su correo electrónico junto con la actualización de su nueva contraseña. Para ello podríamos tener una clase tal que esta:

package jcantos.demo.cad;

import jcantos.demo.entidades.Usuario;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.util.Log;

public class CADUsuario {
    private static final String METHOD_NAME = "ActualizarUsuario";
    private static final String NAMESPACE = "
http://tempuri.org/";
    private static final String URL = "http://www.jcantos.net/webservice.asmx";
    private static final String SOAP_ACTION = "http://tempuri.org/ActualizarUsuario";

    public void ActualizarUsuario(Usuario usuario){
        try {
             SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
             PropertyInfo pi=new PropertyInfo();
             pi.setName("usuario");
             pi.setValue(usuario);
             pi.setType(usuario.getClass());
             request.addProperty(pi);
             SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
             envelope.dotNet=true;
             envelope.setOutputSoapObject(request);
             envelope.addMapping(NAMESPACE, "Usuario", usuario.getClass());
             HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
             androidHttpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
             androidHttpTransport.debug=false;
             androidHttpTransport.call(SOAP_ACTION, envelope);
             envelope.getResponse();
         } catch (Exception e) {
             Log.e("Servicio_Web",e.getMessage());
         }
    }
}

Como veis las posibilidades son infinitas, así que una vez más que la técnica no coarte las necesidades del cliente. Un abrazo a todos y nos vemos en el próximo post.

Related Posts Plugin for WordPress, Blogger...