Jorge Serrano - MVP Visual Developer - Visual Basic
Disclaimer

Quizás el uso de DataAnnotations en una interfaz no sea precisamente una buena práctica, así que no me aticéis por ahí porque el objetivo de esta entrada no es discutir eso, sino saltarnos esa recomendación y demostrar algunas cosas. De hecho, el uso de DataAnnotations tiene como objetivo también, evitar su uso en interfaces, siendo precisamente en su implementación donde tengamos la libertad de adoptarlas o crear nuestras propias DataAnnotations personalizadas.

Introducción

El título dicho así, puede sonar un poco drástico, pero sí,… usar DataAnnotations en nuestras interfaces no es una buena idea, y en esta entrada lejos de aceptar los axiomas que algunos creen porque otros dicen que es así y punto, voy a explicarte de forma práctica porqué digo esto.

¿Qué es o que son las DataAnnotations?

Aunque mucha gente sabe situar perfectamente DataAnnotations, me veo en la obligación de hacer una pequeña parada para indicar que son por si te pilla de nuevas o no lo tienes claro del todo.

El atributo de validación System.ComponentModel.DataAnnotations tiene como misión la validación de los campos de un modelo de datos, e incluso de una entidad si queremos.

Gracias al atributo DataAnnotations, podemos validar nuestros modelos o incluso crear nuestras propias validaciones personalizadas.

Es bastante común encontrarnos con DataAnnotations en aplicaciones web ASP.NET MVC, aunque no se nos impide para nada el uso de DataAnnotations en aplicaciones Web API, de consola o cualquier otra. De hecho, el uso de validaciones de los campos con los que va a trabajar nuestra aplicación no lo considero una opción.

Una vez introducido de forma breve lo que son DataAnnotations, vamos al cubrir de lleno el objetivo de esta entrada, que es el de explicarte por qué a mi juicio no es una buena idea utilizarlas en nuestras interfaces (por si creías que sí).

Desarrollo de un ejemplo simple con DataAnnotations

Lo primero que vamos a hacer es crear una aplicación de consola, dentro de la cual crearemos un modelo o entidad llamada Employee.

Dicha entidad tendrá dos sencillos campos. Nombre (Name) y Edad (Age).

Sobre el campo Age agregaremos una DataAnnotation que nos indicará que el valor de esta propiedad tendrá que estar comprendido entre 18 y 150.

Nuestra entidad quedará de la siguiente manera:

Employee

using System.ComponentModel.DataAnnotations;

namespace ConsoleApplication1
{

   
public class Employee : IEmployee
   
{

       
public string Name { get; set; }

       
[Range(18, 150)]

       
public byte Age { get; set; }

   
}

}

La propiedad Age de nuestro modelo está decorado con una DataAnnotation de tipo Range.

Sin embargo, a la hora de validar nuestro modelo o entidad en nuestra aplicación de consola, deberemos hacer uso de una función que se encargará de validarlo entero, permitiéndonos mostrar por pantalla el campo o campos que no cumplen la condición de validación.

Este método que nos hemos creado podría bien ser el siguiente:

public static bool DataAnnotationsValidator(object @object, out List<ValidationResult> results)
{
   
var context = new ValidationContext(@object, serviceProvider: null, items: null);
   
results = new List<ValidationResult>();
   
return Validator.TryValidateObject(@object, 
                                                  
context,  
                                                  
results, 
                                                  
validateAllProperties: true);
}

Y la llamada a este método desde nuestra aplicación de consola para forzar el error de validación sería:

        static void Main(string[] args)
       
{
           
Console.WriteLine("Ejecución iniciada");
           
Employee employee = new Employee();
           
employee.Name = "John";
           
employee.Age = 17;
           
var results = new List<ValidationResult>();
           
var modelIsValid = DataAnnotationsValidator(employee, out results);
           
Console.WriteLine(String.Format("¿Es el modelo válido? {0}", modelIsValid.ToString()));
           
if (!modelIsValid)
           
{
               
foreach (var validationResult in results)
               
{
                   
Console.WriteLine(validationResult.ErrorMessage);
               
}
           
}
           
Console.WriteLine("Ejecución finalizada");
           
Console.ReadLine();
       
}

Nuestra aplicación en ejecución queda de la siguiente manera:

Como podemos observar, nuestra aplicación funciona tal y como esperamos.

Ampliando nuestro ejemplo

Ahora bien, de repente nos llega un requisito funcional que debemos cubrir.

Supongamos que nos han encargado tratar también los empleados externos.

Un empleado externo según los requisitos que nos han hecho llegar, tendrá los mismos campos que un usuario más el campo empresa, que indicará la empresa a la que pertenece este trabajador externo.

Aquí tenemos muchas posibilidades, pero dentro del equipo de arquitectura y del equipo técnico, entre las opciones de crear una clase abstracta, una clase base o una interfaz, o modificar el modelo para que cubra ambas opciones, se ha pensado que la mejor forma de abordar esto sea con una interface.

Alguien ha pensado incluso y después de las reuniones mantenidas con la gente de negocio (básicamente RRHH en nuestro ejemplo ficticio), que es posible que en un futuro próximo haya además de los empleados internos y los empleados externos, otros empleados,… o que quizás las propiedades nombre y edad usadas en el modelo empleado, pueda ser reutilizado por otros modelos o entidades, así que no es mala idea hacer esto (aceptamos pulpo en nuestro ejemplo).

Así que hagamos un esfuerzo más e imaginemos que nuestro proyecto no sólo posee la entidad Employee, sino que hay cerca de 50 ó más entidades o partes del modelo, y que esta interfaz nos va a venir muy bien porque de un plumazo vamos a reutilizar bastante código, y poniendo una DataAnnotation en una interfaz, resolveremos el problema de tener que poner la validación de rango en todas y cada una de las entidades. No parece mala idea… a priori…

Es decir,… nuestra interfaz y clases quedarán ahora de la siguiente manera:

IEmployee

using System.ComponentModel.DataAnnotations;

namespace ConsoleApplication1
{
    
   
public interface IEmployee
   
{
       
byte Age { get; set; }
       
[Range(18, 150)]
       
string Name { get; set; }
   
}
}

Employee

using System.ComponentModel.DataAnnotations;

namespace ConsoleApplication1
{
   
public class Employee : IEmployee
   
{
       
public string Name { get; set; }
       
public byte Age { get; set; }
   
}
}

ExternEmployee

using System.ComponentModel.DataAnnotations;

namespace ConsoleApplication1
{
   
public class ExternEmployee : IEmployee
   
{
       
public string Company { get; set; }
       
public string Name { get; set; }
       
public byte Age { get; set; }
   
}
}

Bien… ahora ejecutemos nuevamente nuestra aplicación de consola.

Obtendremos una respuesta como la que se indica a continuación:

Como podemos apreciar en la respuesta de ejecución de nuestra aplicación, el modelo o entidad Employee nos indica que es correcta.

¿Cómo es posible?.

Es evidente que la interfaz nos está indicando que la propiedad Age debe estar dentro de un rango de valores que no cumple. Pero como podemos ver, a la hora de ejecutar la acción de validación no está funcionando como esperábamos.

Modificando nuestro ejemplo

Bueno… el equipo de desarrollo se ha reunido para tratar de entender un problema que está sucediendo y que se nos ha escapado en algún momento.

Se ha dedicado bastante tiempo, un tiempo perdido al fin y al cabo, así que después todo este camino recorrido se decide cambiar la interfaz por una clase abstracta.

Esta clase abstracta es la siguiente:

EmployeeAbstract

using System.ComponentModel.DataAnnotations;

namespace ConsoleApplication1
{
    
   
public abstract class EmployeeAbstract
   
{
       
byte Age { get; set; }
       
[Range(18, 150)]
       
string Name { get; set; }
   
}
}

Y nuestras clases anteriores quedarán de la siguiente manera:

Employee

using System.ComponentModel.DataAnnotations;

namespace ConsoleApplication1
{
   
public class Employee : EmployeeAbstract
   
{
       
public string Name { get; set; }
       
public byte Age { get; set; }
   
}
}

ExternEmployee

using System.ComponentModel.DataAnnotations;

namespace ConsoleApplication1
{
   
public class ExternEmployee : EmployeeAbstract
   
{
       
public string Company { get; set; }
       
public string Name { get; set; }
       
public byte Age { get; set; }
   
}
}

Si ejecutamos nuevamente nuestro código, obtendremos un resultado como el que se indica a continuación:

Y aunque no lo voy a hacer aquí, exactamente igual ocurrirá si creamos una clase base que sea heredada por Employee y ExternEmployee.

¿Y esto por qué ocurre?.

El porqué de las cosas

La explicación de este comportamiento tenemos que buscarlo en el CLR de .NET y como funciona por dentro de acuerdo a como quiere que se comporte el equipo de .NET. No obstante, y para comprenderlo mejor, vamos a hacer alguna reflexión previa.

Las clases base son heredadas, tal y como he comentado anteriormente, es decir, los métodos, propiedades y funciones de una clase base, estarán presentes en la clase que la hereda. Por esta razón, una DataAnnotation de una clase base, estará en la clase que lo hereda, en la clase derivada.

Las interfaces por otra parte, son contratos o implementaciones a llevar a cabo, y dichas implementaciones no están presentes en la clase que implementa la interfaz hasta que esta implementación se representa como tal. Esto significa por extensión, que un metadato presente en una interfaz, NO es agregado dentro de la clase que implementa dicha interfaz. Por esta razón, si una interfaz tiene una DataAnnotation, ésta no llega a la clase que implementa esa interfaz.

Pero podemos dar una vuelta de tuerca más a este asunto. Imaginemos que tenemos una clase que implementa dos interfaces, y que estas dos interfaces poseen ambas la misma propiedad, pero con la salvedad de que una de ellas tiene una DataAnnotation y otra no, o dos DataAnnotations diferentes… ¿cual de ellas es la que tenemos que usar?.

Sin embargo, las interfaces chocan en cuanto a su implementación y uso con las clases abstractas, que son otra cosa diferente y posee la herencia como parte fundamental, algo que hemos visto, sí está soportado de forma directa.

Recientemente y por motivos de rendimiento, he tenido que desinstalar de mi Visual Studio 2013 el complemento ReSharper.

El problema, es que una vez desinstalado y reiniciado el entorno de desarrollo, he perdido el Intellisense.

No digo con esto que haya causa/efecto, simplemente constato un hecho que me ha pasado a mí, algo que no merece discusión.

Lo importante de todo este asunto, es que Intellisense es como un perro guía. Inicialmente he estado programando sin Intellisense sin muchos problemas, pero desde luego, no es la mejor forma de trabajar si lo que quieres es productividad. Una ayuda es siempre bienvenida.

El problema aquí es, ¿cómo puedo recuperar el Intellisense en mi Visual Studio?.

Para hacerlo, basta con ir a Tools > Import and Export Settings.

Aparecerá una ventana que corresponde con un asistente.

La primera página del asistente nos presenta tres opciones. Seleccionaremos la opción Reset all settings (normalmente la última) y pulsaremos el botón Next.

En la siguiente página del asistente nos dirá que donde deseamos guardar la configuración actual antes de reiniciarlas, a lo cual debemos seleccionar la segunda opción, No, just reset settings, overwriting my current settings. A continuación pulsaremos el botón Next.

En la siguiente y última página del asistente, deberemos seleccionar el lenguaje de programación correspondiente a la configuración que deseamos resetear, que en mi caso es C#. Finalmente pulsaremos el botón Finish para concluir el proceso.

Aparecerá una ventana con una barra de progreso que nos indicará simplemente que se está llevando a cabo los cambios.

Unos minutos después, aparecerá una ventana confirmándonos que los cambios se han realizado.

Volveremos a nuestro código dentro de Visual Studio 2013, y observaremos que ahora sí, tenemos Intellisense.

Espero que estos pequeños pasos le sirvan a aquellos que tengan alguna vez un problema parecido al mío.

Publicado por Jorge Serrano | 1 comment(s)
Archivado en:

Introducción

Sé que hay gente que sigue la máxima de la información es poder, y de obtener información y conocimiento de muchos sitios y no compartir nada con el resto, algo que respeto pero que no comparto, ya que entre todos podemos recorrer más camino que uno sólo.

Pero lo mejor de todo es que no estoy sólo en ese camino, y me uno al grupo de entusiastas y apasionados de la tecnología que piensan igual que yo.

El caso es que recientemente, dos de esos apasionados escribieron en sus blogs un par de entradas precedidas antes por Twitter y a la que siguieron algunos comentarios muy interesantes.

En la primera de ellas, Luis Ruiz Pavón nos habló de como sobreescribir ToString en nuestras clases para mejorar la información en modo de depuración.

Otro fenómeno como es Eduard Tomás, complementó aquella entrada con otra no menos excelente titulada TIP – DebuggerDisplay.

Lo bueno es que leyendo estas entradas, uno reflexiona, piensa y recuerda, como así ha sido el caso, de la existencia de otras clases, en este caso de DebuggerBrowsable, del que quiero hablar aquí, y cuya existencia pasa muchas veces desapercibida para los desarrolladores, pero que creo complementa a las dos excelentes entradas de Luis y Eduard.

El objetivo de la depuración

El objetivo principal de la depuración es el de preguntar o interrogar como se están comportando nuestros procesos y nuestros objetos, sus flujos y qué información va y viene.

El problema a veces, es que manejamos gran cantidad de información en pantalla que nos impide ver con relativa facilidad algunos miembros o variables. Dicho de otro modo, hay miembros y variables cuya información no nos resulta relevante y… nos estorba cuando estamos depurando.

Por suerte, dentro de .NET tenemos la posibilidad de utilizar un atributo, de nombre DebuggerBrowsable, que nos permite ocultar o mostrar un nivel por encima aquellos miembros que nos interesa ver de un vistazo rápido.

La mejor manera de comprender esto bien, es haciendo un ejemplo, así que nos pondremos manos a la obra con C#.

Entendiendo el problema

En primer lugar, mostraremos el problema para posteriormente resolverlo.

Iniciaremos un proyecto de WinForms (aunque puede ser cualquier otro).

Crearemos dentro de él, dos clases. Una clase de nombre Team, y otra clase de nombre Driver.

Serán dos clases muy sencillas.

La primera clase Team tendrá el siguiente código:

namespace WindowsFormsApplication1
{
    public class Team
    {
 
        public string TeamName { get; set; }
        public string Country { get; set; }
        public Driver Name { get; set; }
    }
}

La segunda clase Driver tendrá el siguiente código:

namespace WindowsFormsApplication1
{
    public class Driver
    {
        public string Name { get; set; }
        public string Surname { get; set; }
        public byte Age { get; set; }
    }
}

Como podemos observar, son dos clases muy sencillas.

La primera corresponde a los datos de un equipo de Formula1, y la segunda contiene los datos de su primer piloto, con su nombre, apellido y edad.

Por su parte, nuestro formulario Windows contendrá el siguiente código fuente:

namespace WindowsFormsApplication1
{
    public partial class MainForm : Form
    {
 
        public MainForm()
        {
            InitializeComponent();
            Initialize();
        }
 
        private Team Formula1Team { get; set; }
 
        private void MainForm_Load(object sender, EventArgs e)
        {            
        }
 
        private void Initialize()
        { 
            this.Formula1Team = new Team() { TeamName = "Ferrari", 
                                             Country = "Italy", 
                                             Name = new Driver() 
                                                    { 
                                                        Name = "Fernando", 
                                                        Surname = "Alonso", 
                                                        Age = 32 
                                                     } 
                                            };
        }
 
    }
}

A continuación, pondremos un punto de interrupción después de agregar un objeto de tipo Team a Formula1Team y veremos la información que nos devuelve el depurador al posicionarnos encima de la propiedad Formula1Team.

La primera información que veremos en la que se indica en la siguiente imagen:

Algo que a todas luces es correcto.

Sin embargo, si queremos acceder a Name, observamos que es del tipo Driver, y nos obliga a hacer clic sobre Name para ver el contenido de esta clase:

El problema aquí es que hemos realizado dos pasos hasta llegar a parte de la información que nos interesaba.

¿Cómo resolver esto?. ¿Tenemos alguna manera de obtener la información que deseamos de un solo plumazo en el visualizador de depuración?.

La respuesta nos la da DebuggerBrowsable, el cual aún no hemos utilizado.

Entendiendo DebuggerBrowsable

Una vez que entendemos un poco la problemática (no en todos los proyectos nos encontraremos con esta problemática o con la necesidad que he expuesto como ejemplo), vamos a ver como resolverlo. Para ello, utilizaremos el atributo DebuggerBrowsable.

Este atributo pertenece al namespace System.Diagnostics, y puede ser agregado a propiedades y campos en clases y estructuras.

Por su parte, tiene tres valores enumerados posibles pertenecientes a DebuggerBrowsableState que son:

  • Collapsed: muestra el objeto contraído, pero permite visualizar el miembro y expandirlo con el objetivo de acceder a cualquier otro miembro que lo pueda contener.
  • Never: no muestra nunca el elemento.
  • RootHidden: oculta el elemento raiz, mostrando los elementos secundarios en el caso de que el elemento sea una colección o matriz de elementos.

Un detalle de este uso es que podemos combinar estos atributos dentro de las diferentes clases. En el ejemplo anterior, tenemos un objeto de tipo Team que contiene a su vez datos de tipo Driver.

En nuestro caso, lo que nos interesa es mostrar en el depurador la información del nombre del equipo y el nombre y apellido del piloto principal del equipo.

Empezaremos por el final.

El objetivo es que el depurador nos muestre una información similar a la que se indica a continuación:

Como podemos observar, lo que obtenemos por pantalla en nuestro caso, es más relevante y nos ayuda a centrarnos en la información que consideramos clave o más importante a la hora de depurar.

El código de nuestras clases Team y Driver, quedarán de la siguiente manera en este caso:

La clase Team quedará de la siguiente forma:

using System.Diagnostics;
 
namespace WindowsFormsApplication1
{
    public class Team
    {
 
        public string TeamName { get; set; }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        public string Country { get; set; }
        [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
        public Driver Name { get; set; }
    }
}

La clase Driver quedará de la siguiente forma:

using System.Diagnostics;
 
namespace WindowsFormsApplication1
{
    public class Driver
    {
        public string Name { get; set; }
        public string Surname { get; set; }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        public byte Age { get; set; }
    }
}

Obviamente, el resto de miembros del objeto está ahí y no han desaparecido. El Intellisense los localiza sin problemas y podemos acceder a ellos desde código.

Sin embargo y como podemos apreciar, el uso de este atributo nos puede venir bien en diferentes situaciones. Ahí cada uno debe saber si le aporta valor o no.

Si tienes un mando de Xbox One en casa, deberías saber que ya es posible utilizarlo en tu tableta o PC.

Microsoft ha liberado los drivers de 32 bits y 64 bits para poder utilizar el mando de la Xbox One en Windows.

Es bastante probable que los drivers se incluyan en un futuro a través de Windows Update, pero mientras tanto, puedes ya instalártelos y probarlos.

Descarga del driver de 32 bits.
Descarga del driver de 64 bits.

Publicado por Jorge Serrano | 1 comment(s)
Archivado en:

Introducción

Si eres de esas personas que tienes un ordenador con Windows y Mac, y tienes la necesidad de compartir información entre ambos ordenadores, o bien quieres pasar información a un disco duro externo o lápiz USB para usarlo en diferentes sistemas, te habrás encontrado con un típico problema.

En mi caso, dispongo de muchísimas fotos en formato RAW que quiero post-procesar con Adobe Photoshop, y para ello, a veces uso Windows y a veces uso Mac. No tengo problema en usar uno u otro, pero las imágenes las quiero tener un disco duro externo de 1 Tb y volcarlas también al disco duro cuando me apetezca desde uno y otro sistema operativo.

Formateando para Windows

Si usas Windows y formateas el disco duro, lo normal es formatearlo en formato NTFS.

El problema es que si introduces ese disco duro en un Mac, éste accederá a él en modo lectura.

Otra posibilidad es formatear el disco duro a formato FAT32. En este caso, el disco duro será accesible tanto para Windows como para Mac, pero el problema aquí es el límite de los archivos que deben tener un tamaño máximo de 4 Gb, lo cuál no es válido ya que es posible que tenga videos hechos con mi cámara de más tamaño, por lo que no es para mí una opción válida.

Formateando para Mac OS X

Si usas Mac y formateas el disco duro, lo normal es formatearlo en formato HFS+.

El problema es que si introduces ese disco curdo en un sistema Windows, ni siquiera será capaz de leerlo.

La solución

La solución a tomar entonces y en mi caso, es realmente sencilla.

Basta con formatear el disco duro a formato exFAT desde Windows.

El formato exFAT es una versión de formateo que mejora a FAT32. Es recomendable su uso en dispositivos USB.

Si no estoy equivocado, para poder usar exFAT en Mac OS X, deberás estar seguro de disponer de un sistema operativo Snow Leopard (v10.6.5) o superior. En el caso de Windows, tu sistema operativo deberá ser Windows Vista o superior.

De esta manera, podremos leer y escribir archivos desde Windows o desde el Mac, pudiendo ser esos archivos de más de 4 Gb, eliminando todas las barreras que teníamos antes.

Si tenemos curiosidad por los diferentes formatos de los discos duros, diferencias y características, te recomiendo acceder a esta información.

Publicado por Jorge Serrano | 2 comment(s)
Archivado en: ,

A finales del pasado 2013, Microsoft anunció la inminente salida de Office 365 Message Encryption.

A finales del mes de Febrero de 2014, se anunció la disponibilidad de Office 365 Message Encryption.

Office 365 Message Encryption es un servicio que nos permite enviar mensajes encriptados a destinatarios fuera de la organización.

Este tipo de servicio está pensado para empresas que posean comunicaciones donde este tipo de comunicación es esencial o muy importante.

Evidentemente, cualquiera puede subscribirse a él para usarlo, pero no es lo habitual.

Pero Office 365 Message Encryption no es nuevo, de hecho es un sustituto de EHE o Exchange Hosted Encryption.

Por otro lado, Office 365 Message Encryption se activa como servicio adicional con un incremento en el coste de aproximadamente 1,50€ por usuario al mes, a excepción de los usuarios de Office 365 E3 y Office 365 E4 para los que este servicio es gratuito. Esto último es así ya que Office 365 Message Excryption forma parte de Microsoft Azure Rights Management, que ya está incluido en las subscripciones E3 y E4 de Office 365.

De cara al administrador, éste deberá habilitar o deshabilitar a través de las reglas de transporte, el uso de Office 365 Message Encryption.

Publicado por Jorge Serrano | 1 comment(s)
Archivado en:

Introducción

Recientemente, Microsoft ha publicado un conjunto de APIs para acceder a Office 365 desde nuestras aplicaciones.

En esta entrada, vamos a introducirnos en el uso y consumo de las APIs de Office 365 desde .NET, en concreto, desde una aplicación de Windows Forms, aunque el tipo de interfaz que usemos no representa en principio ningún problema.

¿Qué nos ofrece las APIs de Office 365?

Las APIs de Office 365 nos ofrece un acceso rápido y sencillo al calendario, correo, contactos, ficheros, etc., de Office 365, reduciendo el tiempo de desarrollo y complejidad a la hora de acceder a estos recursos, abstrayéndonos de ciertas operaciones.

En esta entrada, veremos a modo de prueba de concepto y demostración, como acceder a los contactos de Office 365.

Primeros pasos

Nuestro objetivo principal será el de acceder a las APIs de Office 365 de forma sencilla desde Visual Studio para programar nuestra aplicación.

Para ello, deberemos descargar e instalar en primer lugar (si no lo hemos hecho ya) las Office 365 API Tools para Visual Studio (nota: los ejemplos de código de esta entrada han sido probados con Visual Studio 2013 Update 2).

La descarga de Office 365 API Tools para Visual Studio la encontrarás en este enlace.

Creación de nuestra aplicación

Una vez que hemos instalado las Office 365 API Tools, iniciaremos Visual Studio y crearemos un nuevo proyecto, que en mi caso ha sido un proyecto de Windows Forms al que he puesto por nombre WinFormsOffice365.

A continuación, deberemos hacer clic con el botón derecho del ratón sobre el proyecto que hemos creado y seleccionaremos la opción Add > Connected Service del menú contextual, tal y como aparece en la siguiente imagen:

En la ventana que aparecerá, deberemos conectarnos a nuestra cuenta de Office 365 e indicar sobre qué parte de Office 365 queremos acceder, y los permisos que queremos tener (lectura, escritura, etc).

En esta entrada accederemos a los contactos de nuestra subscripción de Office 365, por lo que he seleccionado el servicio Contacts y le he dado permisos de lectura y escritura.

Los permisos se pueden otorgar seleccionando el servicio al que queremos acceder, y haciendo clic en la opción Permissions.

Una vez modificado todo esto, nuestra ventana debería ser similar a la que se indica a continuación:

Pulsaremos el botón OK y acudiremos al código de nuestra aplicación.

Al realizar esta operación, Visual Studio agrega a nuestro proyecto un conjunto de ensamblados que muy posiblemente necesitemos utilizar a la hora de trabajar con la API de Office 365.

De aquí, los más destacables son:

  • Microsoft.Office365.Exchange
  • Microsoft.Office365.OAuth
  • Microsoft.Office365.OAuth.WindowsForms

Respecto al último, al estar trabajando con una aplicación de Windows Forms, se nos agrega un ensamblado específico del tipo de aplicación con la que estamos trabajando.

Por otro lado, por defecto aparecerá una clase de nombre ContactsApiSample en nuestro código que tendrá el siguiente aspecto:

   1: using Microsoft.Office365.Exchange;
   2: using Microsoft.Office365.OAuth;
   3: using System;
   4: using System.Collections.Generic;
   5: using System.Threading.Tasks;
   6:  
   7: namespace WinFormsOffice365
   8: {
   9:     public static class ContactsAPISample
  10:     {
  11:         const string ExchangeResourceId = "https://outlook.office365.com";
  12:         const string ExchangeServiceRoot = "https://outlook.office365.com/ews/odata";
  13:  
  14:         public static async Task<IEnumerable<IContact>> GetContacts()
  15:         {
  16:             var client = await EnsureClientCreated();
  17:  
  18:             // Obtain first page of contacts
  19:             var contactsResults = await (from i in client.Me.Contacts
  20:                                          orderby i.DisplayName
  21:                                          select i).ExecuteAsync();
  22:             
  23:             return contactsResults.CurrentPage;
  24:         }
  25:     
  26:         private static async Task<ExchangeClient> EnsureClientCreated()
  27:         {
  28:             Authenticator authenticator = new Authenticator();
  29:             var authInfo = await authenticator.AuthenticateAsync(ExchangeResourceId);
  30:  
  31:             return new ExchangeClient(new Uri(ExchangeServiceRoot), authInfo.GetAccessToken);
  32:         }
  33:         public static async Task SignOut()
  34:         {
  35:             await new Authenticator().LogoutAsync();
  36:         }
  37:     }
  38: }

Aunque esta clase nos puede resultar de mucha ayuda, vamos a crear nuestra propia clase con algunas cosas más.

Extendiendo nuestra aplicación

Nuestra aplicación se encargará de mostrar los contactos de nuestra subscripción y de crear nuevos contactos.

En estos momentos, nuestra subscripción tiene un conjunto de contactos tal y como se muestra en la siguiente imagen:

Para darle un poco de gracia a nuestra aplicación Windows, he agregado en ella un conjunto de controles (RichTextBox, Button, Label, LinkLabel, GroupBox, PictureBox…).

La idea como decía antes, es la de permitir mostrar dos acciones principales sobre Office 365 APIs: la posibilidad de acceder y visualizar los contactos de Office 365, y la opción de agregar un nuevo contacto a Office 365.

El aspecto de nuestro formulario Windows es el que se muestra en la siguiente imagen:

Pero lo que realmente nos importa es como podemos trabajar con Office 365 APIs.

Manos a la obra

Para ello, vamos a escribir una clase, que será muy parecida a la que Microsoft nos proporciona en modo prueba y cuyo código compartía anteriormente.

La única salvedad o diferencia es que vamos a agregar alguna instrucción de código más como la inserción de un nuevo contacto y alguna cosa más.

El código de nuestra clase a la que he puesto por nombre Office365Contact es el que se indica a continuación:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Threading.Tasks;
   4: using Microsoft.Office365.Exchange;
   5: using Microsoft.Office365.OAuth;
   6:  
   7: namespace WinFormsOffice365
   8: {
   9:     public class Office365Contact
  10:     {
  11:  
  12:         private const string ExchangeResourceId = "https://outlook.office365.com";
  13:         private const string ExchangeServiceRoot = "https://outlook.office365.com/ews/odata";
  14:  
  15:         private ExchangeClient _exchangeClient;
  16:  
  17:  
  18:         private bool _isAuthenticated = false;
  19:  
  20:         public bool IsAuthenticated 
  21:         {
  22:             get
  23:             {
  24:                 return _isAuthenticated;
  25:             }
  26:         }
  27:  
  28:  
  29:         private AuthenticationInfo _authenticationInfo;
  30:         public AuthenticationInfo AuthenticationInfo
  31:         {
  32:             get { return _authenticationInfo; }
  33:         }
  34:         
  35:         public async Task<ExchangeClient> EnsureExchangeClient()
  36:         {
  37:             if (_exchangeClient != null)
  38:                 return _exchangeClient;
  39:  
  40:             var authenticator = new Authenticator();
  41:             _authenticationInfo = await authenticator.AuthenticateAsync(ExchangeResourceId);
  42:  
  43:             _exchangeClient = new ExchangeClient(new Uri(ExchangeServiceRoot), _authenticationInfo.GetAccessToken);
  44:             _isAuthenticated = true;
  45:             return _exchangeClient;
  46:         }
  47:  
  48:         public async Task<IEnumerable<IContact>> GetAll()
  49:         {
  50:             var client = await EnsureExchangeClient();
  51:             var contactsResults = await client.Me.Contacts.OrderBy(c => c.DisplayName).ExecuteAsync();
  52:             return contactsResults.CurrentPage;
  53:         }
  54:  
  55:         public async Task Create(Contact contact)
  56:         {
  57:             if (contact == null)
  58:             {
  59:                 throw new ArgumentNullException("contact");
  60:             }
  61:             var client = await EnsureExchangeClient();
  62:             await client.Me.Contacts.AddContactAsync(contact);
  63:         }
  64:  
  65:         public async Task SignOut()
  66:         {
  67:             _isAuthenticated = false;
  68:             await new Authenticator().LogoutAsync();
  69:         }
  70:  
  71:     }
  72:  
  73: }

Atendiendo al código, podemos ver 4 métodos principales:

  • EnsureExchangeClient se encarga de realizar las operaciones de autenticación con Office 365. En el caso de que no estemos autenticados nos aparecerá una ventana para escribir nuestra cuenta de Office 365 y nuestra contraseña. Una vez hecho esto, aparecerá una información que nos solicita que confiemos en las operaciones que dicha aplicación va a realizar y que en nuestro caso será las operaciones de lectura y escritura de contactos. Esta función también sabrá si ya nos hemos autenticado anteriormente con la aplicación.
  • SignOut se encarga por su parte de eliminar los rastros de autenticación de nuestro usuario con la aplicación y forzarnos la próxima vez a volver a tener que escribir nuestra cuenta de Office 365 y aceptar los permisos de la aplicación como si fuera la primera vez que la ejecutáramos.
  • GetAll por su parte, nos permite obtener los contactos de Office 365. En este ejemplo no se ha tenido en cuenta paginación de datos ni nada parecido, y se ha optado por esta porción de código que nos servirá como PoC.
  • Create por último, se encargará de crear un nuevo contacto. Aquí utilizamos un objeto de tipo Contact. Este objeto pertenece al ensamblado Microsoft.Office365.Exchange que ha sido agregado automáticamente por Visual Studio.

Del resto de código, destacar las direcciones web de Office 365 que utilizaremos internamente para conectarnos y trabajar con Office 365.

El código de la aplicación de Windows Forms (o aplicación cliente si utilizamos un poco de abstracción) es aquí poco relevante en cuanto a la gestión interna de lo que hace, pero en términos generales nos permitirá realizar las siguientes acciones: SignIn para autenticarnos, y una vez autenticados, leer los contactos y agregar un nuevo contacto, pudiendo además, cerrar la sesión.

Ejecutando nuestra aplicación

La primera vez que ejecutamos nuestra aplicación obtendremos por lo tanto una pantalla que nos solicitará las credenciales para acceder a Office 365:

Una vez autenticados, obtendremos una segunda ventana para aceptar los permisos que otorgamos a la aplicación para acceder a la información de nuestra cuenta.

Pulsaremos el botón Aceptar.

Una vez hecho esto, nuestra aplicación de Windows Forms tendrá un aspecto similar al siguiente:

La primera operación que llevaremos a cabo será la de leer los contactos de Office 365, para lo cual haremos clic sobre el botón Read Contacts.

Nuestra aplicación tendrá entonces un aspecto similar al que se indica a continuación:

A continuación y por completar nuestro ejemplo o PoC, vamos a agregar datos en los campos que tenemos más abajo para crear un nuevo contacto.

En mi caso he agregado los datos ficticios de una persona llamada Albert Einstein y he pulsado el botón Create.

Una vez hecho, se mostrará nuevamente los contactos incluyendo a Albert.

Si acudimos ahora a Office 365, observaremos que nuestro nuevo contacto ha sido agregado a Office 365.

Recordar que esta PoC no trata de ser un guía o un patrón de cómo trabajar con las APIs de Office 365, sino únicamente una toma de contacto.

El código fuente de todo este ejemplo (cliente incluido) puedes encontrarlo en este enlace.

Conclusiones

Aunque en esta prueba de concepto hemos repasado únicamente las operaciones de lectura y obtención de todos los contactos, y de creación de un contacto en Office 365, podríamos haber llevado a cabo todas las operaciones CRUD.

También cabe destacar que en nuestro caso, hemos realizado operaciones con los contactos de un usuario, pero podríamos haber realizado operaciones con el calendario, correo, ficheros, etc.

Happy coding!

Publicado por Jorge Serrano | con no comments
Archivado en:

Introducción

Una pregunta muy típica de los administradores de Office 365 es la que tiene que ver con los detalles de facturación de nuestras subscripciones de Office 365.

¿Dónde encontrar las facturas e imprimirlas?.

Mi idea con esta pequeña entrada es explicar donde podemos localizarlas, ya que cuando lo hacemos por primera vez no es precisamente intuitivo y muchos usuarios se pierden.

Localizando la facturación de Office 365

Lo más fácil y rápido para ver e imprimir o descargar en disco nuestras facturas de Office 365 es acceder en primer lugar (y como es obvio) a nuestra subscripción de Office 365, en concreto al Centro de Administración de Office 365.

Una vez que hemos accedido a nuestra subscripción, prestaremos atención al menú lateral izquierdo de Office 365, y dentro de este menú, haremos clic en la opción concesión de licencias.

De esta manera, accederemos a todas nuestras licencias dentro de la subscripción de Office 365.

Podemos seleccionar nuestra subscripción y acceder a sus detalles de facturación, licencias, etc.

En nuestro caso tenemos una única subscripción por lo que acceder a la facturación de esta subscripción es realmente sencillo.

Basta con hacer clic sobre la opción del menú horizontal facturación que se encuentra justo encima de nuestra subscripción.

Dentro de esta nueva ventana, podremos acceder a la facturación de cualquier mes del año, verla e imprimirla o exportarla en formato pdf.

Como podemos ver, es más sencillo de lo que podríamos en un primer momento pensar, aunque desde mi modesto punto de vista, está un pelín rebuscado y no es muy intuitivo localizarlo requiriendo algunos pasos intermedios hasta que damos con ello.

Publicado por Jorge Serrano | con no comments
Archivado en:

 

Los que hemos trabajado con SkyDrive Pro en SharePoint 2013, sabemos que a la hora de sincronizar bibliotecas de documentos no funcionaba como era de esperar.

Pues bien, Microsoft ha preparado un pequeño documento técnico para resolver este problema el cual pasa por desinstalar la versión actual de sincronización de datos en la nube, conocida hasta la fecha como SkyDrive Pro, e instalar la nueva aplicación denominada OneDrive for Business.

No tiene mucho sentido explicar punto por punto que se dice en el documento, ya que es muy sencillo seguir los pasos de instalación.

Puedes acceder a esta información en este enlace.

Publicado por Jorge Serrano | con no comments
Archivado en: ,

Introducción

Este sábado pasado, en MsCoders Madrid hicimos un evento de 9:00 a 14:30 meramente técnico y práctico donde la gente tenía la posibilidad de elegir dos sesiones de 6 posibles, divididas en 3 tracks.

Lo único que debían traer era su portátil y ganas, muchas ganas de aprender, compartir y pasar un buen rato.

En mi caso, estuve llevando una de las sesiones, la dedicada a SignalR y cuyo título era “Juegos en tiempo real con SignalR y HTML 5”. Lejos de extenderme respecto a mis impresiones, todas positivas, lo que más me gustó es que no había entradas libres para la sesión, lo cual mostraba el interés de la misma, aunque para ser honesto, creo que hubo gente que se movió de sala o que no pudo finalmente venir porque había algún hueco en la sala.

El caso es que durante la sesión, quise demostrar como SignalR decide qué transporte utilizar dependiendo del cliente y servidor que tengamos (dependiendo de los extremos), pero al final no pude demostrarlo por culpa de un despiste mío (mea culpa, a veces soy un poco despistado). Eso hizo que no me funcionara bien en la demostración cuando lo tenía listo y preparado, pero bueno, lo importante es demostrarlo y eso es lo que quiero hacer aquí, para los que quieran saber como hacerlo.

SignalR y tranportes

Para que SignalR actúe en tiempo real, es necesario que trabaje sobre un transporte adecuado.

Esta adecuación como vimos el sábado (los que pudieron acudir al encuentro) no siempre es tan bonita como la pintan, y es que los extremos “mandan”, aunque podemos forzarlo si bien nos podemos encontrar con desagradables resultados.

Lo importante. SignalR trabaja o puede trabajar con 4 tipos de transportes diferentes.

Dos transportes de HTML5: WebSocket y Server Send Events.

Dos transportes Comet: Forever Frame y Ajax Long Polling.

SignalR intentará siempre que pueda, utilizar WebSockets, pero tal y como vimos no siempre es posible.

Lo mejor de todo es que SignalR hará por nosotros el trabajo de resolver que tipo de transporte utilizar, lo que nos simplifica mucho las tareas de gestión creando esa capa de abstracción que nos evita perder el tiempo con controles, gestión, etc de transporte.

Para demostrar esto, vamos a basarnos en Internet Explorer, aunque podría utilizar más navegadores Web o clientes diferentes. El hecho de basarme en Internet Explorer es porque alguna de sus versiones soporta un tipo de transporte y otras no, y es un ejemplo ideal para demostrar este comportamiento.

Concretamente y para demostrar esto, utilizaremos Internet Explorer 10 en un servidor que soporta WebSocket. Es decir, Internet Explorer 10 soportará WebSocket también.

Y posteriormente, haremos lo mismo en el mismo servidor que soporta WebSocket, pero con Internet Explorer 8, el cual no soporta WebSocket.

Así podremos ver como SignalR gestiona por nosotros el transporte a utilizar.

Internet Explorer y WebSocket

Para llevar a cabo esto, vamos a modificar el cliente, que en mi caso será una página Web, y justo después de establecer la conexión, voy a habilitar las trazas.

$.connection.hub.logging = true;

Agregando esta línea de código y ejecutando nuestra aplicación, veremos cuál es el transporte que vamos a utilizar.

Para Internet Explorer 10, el resultado que obtenemos en la consola es el que se indica en la siguiente imagen (WebSocket):

En el caso de utilizar Internet Explorer 8, el resultado de la consola es diferente (LongPolling):

Finalmente, voy a poner un diagrama sobre la decisión de qué transporte utilizar en SignalR y que me he encontrado en un foro (http://stackoverflow.com/questions/16983630/how-does-signalr-decide-which-transport-method-to-be-used) por si a alguien le viene bien:

Espero que ayude a comprender un poco más como se establece el transporte en SignalR.

Publicado por Jorge Serrano | con no comments
Archivado en: ,

Voy a contar como resolver un problema con el que me he encontrado al lidiar con CRM 4.0.

Accediendo al CRM dentro del servidor con el fin de comprobar varios comportamientos, me he encontrado con que la aplicación Web me marcaba un error general del tipo “Acción no válida. La acción seleccionada no es válida”.

Lo primero que un ser humano piensa es en si el CRM estará bien configurado, pero sí, lo está, y nadie lo ha tocado.

Por esa razón, lo primero que uno hace es acudir a ese sitio que se llama visor de eventos por si encontramos alguna pista, y efectivamente, encuentro una pista que me indica algo así:

Y su detalle algo como:

Current active key (KeyType : CrmWRPCTokenKey) is expired.  This can indicate that a key is not being regenerated properly.  Current Active Key : CrmKey(Id:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee, ScaleGroupId:00000000-0000-0000-0000-000000000000, KeyType:CrmWRPCTokenKey, Expired:True, ValidOn:07/16/2013 11:34:11, ExpiresOn:08/18/2013 11:34:11, CreatedOn:07/16/2013 11:34:11, CreatedBy:NT AUTHORITY\Servicio de red.  Key Setting :

Para resolver este problema, lo que debemos hacer es lo siguiente:

  • Abrir una ventana de consola en el servidor y ejecutar el comando Microsoft.Crm.Tools.WRPCKeyRenewal.exe de la siguiente manera:
    C:\Program Files\Microsoft Dynamics CRM\Tools\Microsoft.Crm.Tools.WRPCKeyRenewal.exe /R
  • A continuación y si todo ha ido correctamente, reiniciar el servicio:
    Servicio de procesamiento asíncrono de Microsoft CRM o Microsoft CRM Asynchronous Processing Service dependiendo del idioma de nuestro servidor.
  • Para acabar, deberemos reiniciar IIS para asegurarnos de que aplicamos los cambios.

Ahora deberemos acceder nuevamente a la aplicación Web de CRM y si todo lo hemos hecho correctamente, deberá funcionar tal y como esperábamos.

Publicado por Jorge Serrano | con no comments
Archivado en:

Introducción

Embarcado en un proyecto con notificaciones toast para Windows Phone8 y Windows Azure Service Bus, me encuentro con un error 412 que dice algo parecido a:

HTTP request failed.

HTTP Details:
Status: 412
Reason: Precondition Failed
Full content: <Error><Code>412</Code><Detail>The ETag header is either missing or invalid. It should be "*", or a quoted ETag..TrackingId:…</Detail></Error>

Lo cierto es que este error nos traía locos, pero como muchas cosas en la vida, al final del túnel hemos encontrado la luz.

La solución

Parece ser que el problema reside en la versión 0.1.7.4 de Windows Azure Service Bus Managed que se puede descargar en Nuget y que tiene un bug.

Basta con actualizar este paquete a su versión 0.1.7.5 de este mes de diciembre de 2013 para resolver el problema.

Obtendréis más información sobre este bug o problema en este enlace de una discusión sobre este tema.

También obtendréis acceso a la versión 0.1.7.5 de Windows Azure Service Bus Managed en este otro enlace.

Para completar la entrada, indicaré un documento en inglés acerca de las notificaciones con Windows Azure Notification Hubs por si alguno quiere saber alguna cosa más al respecto de las notificaciones, etc. lo encontraréis en este enlace How To: Windows Azure Notification Hubs (Windows Store Apps).

Publicado por Jorge Serrano | con no comments

Introducción

Mi compañero de trabajo y MVP de ASP.NET, Luis Ruiz Pavón, ha llegado esta mañana a la oficina con una preocupación.

¡Su hija podría navegar por Internet desde el Kid’s Corner!

Lo que ha sucedido

Resulta que Luis le dejó su móvil Windows Phone 8 a su hija (como muchas otras veces ha hecho) y para ello ha usado la fantástica opción de Windows Phone llamada Kid’s Corner.

Esta característica es ideal para los padres y pueden estar tranquilos dejando a sus hijos usar aplicaciones de Windows Phone previamente seleccionadas sin riesgo… o eso era lo que Luis y otros padres creían hasta hoy claro.

Resulta que Luis se dio cuenta de que su hija (de tal palo tal astilla) estaba haciendo algo más que jugar, por lo que intentó averiguar el qué y vaya si lo hizo. La sorpresa suya fue mayúscula cuando sorprendió a su hija estaba navegando por Internet.

Ante esto, a primera hora de la mañana hemos tratado de reproducir lo fácil que puede resultar hacer estas cosas.

 

Aquí el video:

https://skydrive.live.com/redir?resid=ED7DAD70423E8CE4!794&authkey=!AHxIN2f9UxHTMkk

 

Esperemos que Microsoft tenga en consideración esta característica (¿bug?) para mejorarla e impedir que los niños puedan acceder a información sensible.

Un saludo.

Publicado por Jorge Serrano | 1 comment(s)
Archivado en:

Introducción

De todos es conocido ya la existencia de SkyDrive, pero algunos se pierden al oir hablar de SkyDrive Pro.

Para ponernos en situación, diremos que SkyDrive Pro es el almacenamiento en la nube pensado para empresas, dentro del cual entra en juego Office 365.

La idea detrás de SkyDrive Pro es la de tener un sitio en el que los empleados puedan almacenar sus archivos y documentos, sincronizarlos y compartirlos con otras personas de la organización o de fuera de la organización, entre diversos tipos de dispositivos y desde cualquier lugar.

SkyDrive Pro Apps

Para facilitar la vida al usuario, Microsoft ha creado aplicaciones que nos permita gestionar el contenido de nuestro SkyDrive Pro fácilmente.

En el mes de Junio, Microsoft anunció las aplicaciones para Windows 8 e iOS, que pueden ser descargadas gratuitamente desde Windows Store (Windows 8) y desde la Apple Store (iOS).

Más información en este enlace oficial.

Límites de SkyDrive Pro

Hasta hace unas horas, el límite de SkyDrive Pro es de 7 Gb por usuario.

Un límite que a todas luces y para el ámbito profesional, se presta insuficiente la mayoría de las ocasiones.

Un contratiempo adicional es que no se podía incrementar ese espacio de 7 Gb por usuario, algo que incrementa aún más las molestias de las empresas y de los usuarios.

Muchas han sido las quejas recibidas, por lo tanto, por Microsoft al respecto, quejas que han sido escuchadas.

De hecho, el límite de SkyDrive Pro por usuario ha pasado ya de 7 Gb a 25 Gb como se puede ver en la siguiente imagen.

Mejoras relacionadas con SkyDrive Pro en Office 365

Sin embargo, hay otras mejoras que han sido incluidas en SkyDrive Pro para Office 365. Aquí van las tres mejoras incorporadas y relacionadas con SkyDrive Pro:

  • Cada usuario dispondrá ahora de 25 Gb de espacio en SkyDrive Pro.
  • El almacenamiento por defecto de cada usuario es de 25 Gb, pero podrá ser incrementado a 50 Gb ó 100 Gb según queramos.
  • Se ha creado una funcionalidad (Shared with Me) para localizar fácilmente documentos que otros usuarios han compartido con nosotros.

Como es lógico, sólo el administrador podrá incrementar el espacio de almacenamiento de SkyDrive Pro.

El coste de dicho espacio extra está valorado inicialmente en 0.20 céntimos de dólar $ por giga y por mes.

Adicionalmente, se están trabajando en más mejoras relacionadas con SkyDrive Pro como el versionado por defecto y el límite de tamaño relacionado con los ficheros que queremos subir al almacenamiento en la nube, así como la cantidad de días que se retendrán los ficheros en la papelera de reciclaje cuando son borrados (a no ser que sean borrados permanentemente).

 

Podrás obtener más información en este enlace oficial.

Nota: te recomiendo mirar la FAQ recogida en el enlace oficial anterior.

Publicado por Jorge Serrano | con no comments
Archivado en:

Microsoft ha publicado un documento pdf de 17 Mb denominado .NET Universe 2013 que representa un diagrama que recoge los SDKs de .NET, librerías y paquetes, clasificados por tipo de aplicación y tipo de paquete (NuGet, etc).

Podrás descargar este documento desde este enlace.

Introducción

Es bastante frecuente a veces, sobre todo en el trabajo en equipo, el hecho de que una persona pueda ejecutar un comando de PowerShell concreto y a otra no le funcione ese comando por no tener instalados los cmdlets concretos.

Pero antes de entrar en detalle, haré una obligada parada para explicar que es esto de los cmdlets, sobre todo para aquellos que no estén familiarizados con todo esto.

¿Qué son los cmdlets?

Los cmdlets no son otra cosa que combinaciones de verbos y nombres que juntos forman un comando que actúa sobre un objeto determinado.

Estos verbos (comandos) y nombres (objetos) van separados por un guión.

Un ejemplo es:

Get-MsolUser

Get sería el comando, y MsolUser el objeto. Como podemos apreciar, ambos quedan separados por un guión en medio.

Ahora bien, en muchas ocasiones, nos encontramos como decía al principio, que no tenemos instalados los cmdlets que a lo mejor otro compañero de trabajo posee, o bien, no tenemos los cmdlets que necesitamos utilizar.

¿Cómo poder saber esto?.

Accediendo a la ventana de comandos

Lo primero de todo que debemos hacer es abrir una ventana de PowerShell.

Dentro de la ventana de PowerShell deberemos ejecutar el siguiente comando o instrucción:

Show-Command

De esta forma, se abrirá una ventana de comandos como la que se indica a continuación:

Dentro de esta ventana podremos desplegar la lista de módulos y acceder a los módulos sobre los que queremos comprobar que tenemos acceso, y dentro de sus cmdlets.

Si ahora hacemos clic sobre un cmdlet concreto, accederemos a información ampliada sobre ese cmdlet e incluso podremos ejecutarlo.

Dentro de esta ventana, iremos obteniendo pistas de las instrucciones de PowerShell que deberemos ejecutar.

No obstante, y si queremos, podemos hacer clic sobre el botón Copy para copiar los comandos al portapapeles, o bien hacer clic sobre el botón Run para ejecutar el comando en PowerShell.

Al pulsar el botón de ejecución, se lanzará el comando y obtendremos el resultado en pantalla:

Conclusiones

En esta entrada he hecho una parada en un comando de PowerShell que es muy útil y que conviene conocer por si en algún momento tenemos alguna duda con algún comando de PowerShell concreto o queremos saber si tenemos instalados algunos módulos de comandos o no.

Espero que esta información le sea de ayuda a más de uno.

Publicado por Jorge Serrano | con no comments
Archivado en:

Introducción

La mejor manera de administrar Office 365 es hacerlo a través de la línea de comandos de Microsoft PowerShell.

Sin embargo, para poder hacerlo tendremos que tener acceso a Internet.

Es indudable que este tipo de acciones está en principio pensado para los profesionales informáticos, aunque sino tiene experiencia con Office 365 pero sí con PowerShell, sepa que familiarizarse con todo esto no es extremadamente complejo. Únicamente hay que tener en cuenta algunas cosas y saber qué comandos ejecutar y en qué momento.

Piense que en todo momento estaremos trabajando con entornos en producción, y que cualquier comando mal ejecutado podría acarrear problemas.

Requisitos previos

Los requisitos previos son los siguientes:

  • Windows 7, Windows 8, Windows Server 2008 R2 ó Windows Server 2012. Correctamente actualizados con los últimos parches, etc.
  • Microsoft .NET Framework 3.5.1 ó superior.
  • Instalación de Microsoft Online Services Sign-In Assistant.
  • Instalación de Windows Azure Active Directory Module for Windows PowerShell.

Instalación de los requisitos previos

La instalación del sistema operativo y de .NET Framework la voy a obviar en este punto. Considero que ya lo tenemos instalado.

Sin embargo, sí voy a hacer una parada en los dos siguientes puntos.

Respecto a la instalación de Microsoft Online Services Sign-In, comentar que en principio no da ningún error en su instalación, pero sí la instalación posterior de Windows Azure Active Directory Module for Windows PowerShell.

El error que podemos obtener en pantalla es el siguiente:

Si este es tu caso o quieres evitarte problemas, entonces te recomiendo que primero te instales la versión beta de Microsoft Online Services Sign-In Assistant de fecha 12/06/2013 o bien una versión superior.

Encontrarás este instalable en este enlace (v7.250.4551.0) tanto para versiones de 32 bits como versiones de 64 bits.

Una vez instalado, sí podremos instalar sin problemas Windows Azure Directory Module for Windows PowerShell que podremos encontrar en este enlace (32 bits) o en este otro enlace (64 bits).

Una vez instalado, estaremos listos para poder ejecutar la línea de comandos de PowerShell contra Office 365.

Ejecutando comandos de Office 365 con PowerShell por primera vez

Lo primero que tenemos que tener en cuenta al trabajar con PowerShell es que dentro de nuestro sistema operativo encontraremos seguramente varias aplicaciones que tengan o empiecen por la palabra PowerShell.

En nuestro caso vamos a poder utilizar cualquiera de ellas.

Como recomendación, utilizar el módulo de Windows Azure AD que tiene ya preparados los cmdlets que necesitaremos lógicamente, pero tampoco es problema para poder acceder a los comandos de PowerShell de Office 365.

Si tuviéramos algún problema, recordemos el comando de carga de los cmdlets que necesitaremos utilizar desde PowerShell y que es:

import-module MSOnline

Una vez hecho esto, la primera acción es la de registrarnos con las credenciales de Office 365 para las cuales tenemos permisos.

Para ello, deberemos escribir en nuestra línea de comandos de PowerShell el comando:

Connect-MsolService

Finalmente y para comprobar que estamos accediendo a nuestra subscripción de Office 365 desde PowerShell, ejecutaremos un comando muy sencillo a modo de prueba:

Get-MsolDomain

Obtendremos algo parecido a lo siguiente dependiendo de las características de nuestra subscripción de Office 365:

Conclusiones

Hasta aquí, hemos podido ver como preparar nuestro entorno para ejecutar comandos de Office 365 a través de PowerShell y como ejecutar nuestros primeros comandos contra Office 365.

Tal y como podemos ver y después de establecer la conexión concreta, hemos sido capaces de obtener información de nuestra subscripción.

A partir de aquí, podremos acceder a nuestra subscripción y ejecutar parámetros de diferente naturaleza para realizar las acciones que tengamos que realizar contra nuestra subscripción.

Publicado por Jorge Serrano | 2 comment(s)
Archivado en:

Introducción

Un aspecto típico de los productos Microsoft es el galimatías que presenta siempre las diferentes versiones o subscripciones de un producto de la empresa de Redmond.

Las licencias, características, etc. de cada producto no sería lo mismo sin ese embrollo. Es casi algo religioso que sea así, y claro, Office 365 no es la excepción.

En este caso, voy a hacer un repaso de las versiones de Office 365 para el mundo empresarial, gubernamental y educativo, terminando con dos subscripciones que están aisladas en tierra de nadie.

Mundo empresarial

Dentro del mundo empresarial encontramos 3 bloques principales en los que se aglutinan las diferentes versiones de Office 365:

  • Small business
  • Midsize business
  • Enterprise

Cada bloque posee un conjunto de características determinado, y dentro de ese bloque podemos tener un tipo de subscripción, o más de uno a elegir.

Podremos encontrar más información sobre los planes de subscripción de Office 365 en el mundo empresarial en este enlace.

Mundo gubernamental

Dentro del mundo gubernamental, las subscripciones de Office 365 quedan simplificadas enormemente (Plan 1, Plan 2, Plan E1 y Plan E3).

No es cuestión de explicar punto por punto sus diferencias, así que en este enlace encontraréis información al respecto que creo os aclarará muchas dudas.

Mundo educativo

De la misma que en los casos anteriores, en el mundo educativo Office 365 posee sus propios tipos de subscripciones.

Existen diferencias entre las diferentes subscripciones y planeas (A2, A3 y A4).

En el siguiente enlace podréis encontrar estas diferencias explicadas con detalle.

Office 365 Pro Plus

Finalmente (y no lo he nombrado hasta ahora), existe una subscripción de Office 365 denominada Office 365 Pro Plus y que contiene características de Office 365 para personas individuales o pequeñísimas organizaciones que requieren la funcionalidad de Office 365.

Puedes acceder a más información sobre Office 365 Pro Plus en este enlace.

Office 365 for Home

Otro caso particular de las subscripciones de Office 365 y que tampoco he nombrado hasta el momento, es el de Office 365 for home.

Aquí se reúnen las subscripciones de Office 365 para el hogar, así como las subscripciones de Office 2013 de escritorio.

Puedes ampliar la información de Office 365 for home en este enlace.

Conclusiones

Como podemos apreciar, Microsoft ha tratado de cubrir todas las posibilidades de las empresas, organismos públicos, colegios, pequeñas empresas y personas individuales.

La idea de esta entrada es tratar de poner un poco de orden en las diferentes versiones de Office 365 que hay con el fin de que nadie se líe en exceso y sepa en todo momento qué tipo de subscripción de Office 365 debe adquirir o cuál le conviene.

Espero haber logrado mi propósito.

Publicado por Jorge Serrano | con no comments
Archivado en:

Introducción

En algunas ocasiones, es posible que tengamos la intención o necesidad de crear una cuenta de Office 365 de prueba (conocida en el argot como trial).

El problema es que generalmente cuando creamos una cuenta de prueba de Office 365, Microsoft nos invita a agregar los datos de nuestra tarjeta de crédito o los datos de PayPal, y esto no es siempre del agrado de todos.

Creando una cuenta trial de Office 365 con datos de pago

La mayoría de la gente termina creando un cuenta trial de Office 365 del sitio principal de Microsoft y al final, no queda otra que agregar los datos de tu tarjeta de crédito. Por culpa de esto, mucha gente no termina creando una cuenta de Office 365 de prueba.

Y es que realmente uno siempre termina pensando aquello de si es de prueba, ¿para qué me obliga Microsoft a poner datos sensibles si no tengo intención de que se usen nunca (no al menos de momento)?.

La dirección “maldita” para crear una subscripción de Office 365 de prueba agregando estos datos es la siguiente:

Try Office 365 Home Premium

El problema de este tipo de subscripción es que debemos andar “listos” para que no se renueve automáticamente al cabo del mes de prueba y nos haga coger cierto cabreo.

Creando una cuenta trial de Office 365 intentando no poner datos de pago

Ante esto, la pregunta sería algo así como si existe la posibilidad de crear una cuenta de Office 365 de prueba y que no nos permita agregar estos datos.

Y la respuesta es que sí es posible, que existe la posibilidad de crear una cuenta de Office 365 trial de 1 mes de prueba sin tener que poner este tipo de datos.

La subscripción de Office 365 puede ser de diferentes tipos, pero como ejemplo citaré una subscripción de tipo Office 365 Small Business Premium, a la cuál podremos acceder a ella desde este enlace:

Try Office 365 Small Business Premium

El problema es que no podremos cancelar esta subscripción, y que al mes, será borrada automáticamente.

Nota: en la página Web de Small Business Premium, también podemos seleccionar una versión trial de Office 365 Midsize Business y de Office 365 Enterprise sin necesidad de agregar datos de nuestra tarjeta de crédito u otra forma de pago.

Esto nos evita problemas, pero también, si estamos utilizando esta cuenta para pruebas muy concretas, tenemos que saber que al cabo de 1 mes, perderemos su contenido.

Viene muy bien para hacer pequeños proyectos piloto o de pruebas, o para tratar de convencer a la empresa o a algún cliente de las ventajas que ofrece el producto.

Otros datos de interés

Finalmente, indicaré las características de Office 365 Home Premium y la información de Office 365 Small Business Premium por si alguien quiere compararlas.

Espero que con esta entrada, la gente no tenga problemas en crear su subscripción de Office 365 sin tener que temer poner datos sensibles de carácter personal.

Publicado por Jorge Serrano | con no comments
Archivado en:

Introducción

En las próximas fechas, tengo la intención de escribir diferentes entradas sobre Office 365 con el fin de ayudar a adoptar y administrar las aplicaciones englobadas en esta suite.

Creo que esta debería ser la primera entrada que espero y deseo sirva de ayuda. Es posible que muchos de vosotros ya sepáis lo que es Office 365, pero por si acaso hay algún despistado, creo que es interesante recalcarlo, para que nadie se pierda. :)

Office 365 para todos

Antes de entrar en la definición pura del producto, querría desmitificar una cosa.

Office 365 no es sólo para empresas.

Es decir, Office 365 es un producto que está pensado para cualquier tipo de público, lo que ocurre es que posee un carácter marcadamente empresarial, desde pequeñísimas empresas hasta grandes empresas, pero eso no significa que Office 365 no pueda ser utilizado por cualquier persona individual que no pertenezca a ninguna organización.

De hecho, Office 365 es en sí, un producto global, y como tal, tiene cabida para cualquier usuario.

Office 365 y Office 2013

Llegados a este punto, conviene destacar que Office 365 no es lo mismo que Office 2013.

Si queremos trabajar con Office como lo hemos hecho hasta ahora, basta con instalarse el paquete de Office 2013 en nuestros escritorio y trabajar como hemos hecho siempre.

Ahora bien, si lo que queremos es sacar el máximo provecho a nuestra movilidad geográfica, etc., lo ideal es tener Office 365, y como excelencia, combinar Office 365 y Office 2013.

Office 365 no es otra cosa que un conjunto de herramientas de colaboración y trabajo dispuestas en la nube, en Internet. De hecho, todas las herramientas de Office 365 las conocerá con la palabra final Online.

La beta de Office 365 apareció en Octubre del 2010, y la primera versión en producción en Junio del 2011. A lo largo de estos dos años ha ido incorporando mejoras y características nuevas. Es por lo tanto, un producto en expansión y crecimiento, y que ya ha pasado la etapa de estabilización.

Dentro de Office 365 tenemos la posibilidad de trabajar con Word, Excel, PowerPoint, Exchange para recibir y enviar correos electrónicos en el escritorio y en dispositivos móviles, Lync para conversaciones con texto, audio y/o video, crear y administrar reuniones y agendas, un disco duro virtual para almacenar nuestra información, posibilidad de utilizar las características de SharePoint para organizar la información y trabajar en equipo, etc.

Dicho de una manera, es tener la suite de Office con más añadidos y en la nube, ofreciéndonos la posibilidad de colaborar y trabajar sin dar importancia al sitio, ciudad o país en el que nos encontremos.

Office 365 e Internet

Office 365 tiene una especial relación con Internet, lo cuál significa que en muchas ocasiones tendremos que tener una conexión a Internet para poder utilizar sus servicios.

La nube es así, e igual que cuando llegas a casa y enciendes la luz se supone que tienes un contrato con una compañía hidroeléctrica que te sirve el servicio para poder iluminar las bombillas de tu casa, en este caso ocurre más o menos lo mismo pero con la red de redes.

Requisitos mínimos para trabajar con Office 2013

Según Microsoft, para poder utilizar Office necesitará un sistema operativo Windows 7 ó Windows 8, o Mac OS X versión 10.6 ó superior.

Office Mobile lo podrá instalar a su vez en dispositivos móviles iPhone, y está disponible de serie en móviles Windows Phone.

Office 365 y la competencia

Microsoft Office 365 no es el único producto de estas características. Google por su parte tiene un producto denominado Google Apps que al igual que Office 365 constituye una suite que contiene correo electrónico, trabajo en grupo, calendario, conversación por texto y video, trabajo con documentos de ofimática como Word, Excel, etc. y un disco duro virtual donde alojar tus documentos y archivos.

Google Apps comenzó su andadura en Febrero del 2006 con GMail para empresas, y a lo largo de estos años ha ido incorporando mejoras y características nuevas, un camino largo que aún no se ha detenido. Sin embargo, ha habido decisiones de Google que han sorprendido a la gente como el hecho de que en Diciembre de 2012 se haya tomado la decisión de descontinuar la versión gratuita de Google Apps. En sustitución de ésta, Google anima a usar Google App Engine.

Lo verdaderamente interesante de todo esto es que el usuario tiene opciones en el mercado para elegir la que más le satisface.

Publicado por Jorge Serrano | con no comments
Archivado en:
Más artículos Página siguiente >