lunes, 6 de diciembre de 2010

El Día del Flujo de Trabajo de SharePoint 2010 para Desarrolladores

Solo para invitarlos cordialmente a la serie de webcast sobre flujos de trabajo en SharePoint 2010 que se estará llevando acabo el día 15 de Diciembre del presente año, en donde estaré participando con una charla acerca del uso de Visio Services para el desarrollo de workflows.

Sin duda es una muy buena oportunidad para conocer todo lo referente a los flujos de trabajo en SP 2010, lo que siempre quisiste preguntar pero no habías podido. Esta por demás decir que los expositores son el Jet Set del Desarrollo en SharePoint (excepto yo, que solo estoy de colado)

clip_image001

El miércoles 15 de diciembre del presente año varios MVPs estaran celebrando el día del flujo de trabajo SharePoint 2010 para desarrolladores en donde presentaran los conceptos mas relevantes a relacionados con el desarrollo de flujos de trabajo con Microsoft SharePoint Server 2010 mediante presentaciones abiertas en línea de forma continua durante el transcurso del día.


clip_image002

Conociendo los Flujos de Trabajo Pre Construidos en SharePoint 2010
En esta sesión conoceremos la propuesta de flujos de trabajo que SharePoint 2010 pone en la mesa y las características de cada uno de los flujos de trabajo pre construidos en el producto. Cuando y donde genera valor utilizarlo para automatizar algún proceso u operación empresarial y mejor aún cómo es posible extenderlos para personalizar algún proceso.
15 de Diciembre 2010 a las 10:00 AM Tiempo de México
https://www.livemeeting.com/cc/mvp/join?id=wfday1&role=attend

clip_image003

Construyendo Flujos de Trabajo en SharePoint 2010 utilizando SharePoint Designer 2010
En esta sesión veremos el soporte que SharePoint Designer 2010 tiene para la creación y manipulación de flujos de trabajo para SharePoint. Conozca el nuevo diseñador de flujos de trabajo, las actividades y condiciones disponibles en esta versión y como programar tus propias condiciones y acciones para SharePoint Designer 2010.
15 de Diciembre 2010 a las 11:30 AM Tiempo de México
https://www.livemeeting.com/cc/mvp/join?id=wfday&role=attend

clip_image004

Construyendo Flujos de Trabajo en SharePoint 2010 utilizando Visio Services
En esta sesión veremos el valor que Visio Services aporta al mundo de los flujos de trabajo. Al fin contamos con una alternativa mucho más rica para poder mostrar de forma gráfica el estado de los flujos en ejecución y brindar opciones al usuario para consultar información contextual de una instancia en ejecución del flujo de trabajo.
15 de Diciembre 2010 a las 3:00 PM Tiempo de México
https://www.livemeeting.com/cc/mvp/join?id=wfday3&role=attend

clip_image005

Construyendo Flujos de Trabajo en SharePoint 2010 utilizando Visual Studio 2010
Esta es una sesión para desarrolladores .NET que construyen flujos de trabajo para SharePoint 2007 y buscan conocer cómo construir flujos de trabajo en SharePoint 2010. Exploraremos las nuevas características relacionadas con flujos dentro de SharePoint 2010 y el soporte simplificado Visual Studio 2010 aporta para facilitar su construcción y despliegue.
15 de Diciembre 2010 a las 4:30 PM Tiempo de México
https://www.livemeeting.com/cc/mvp/join?id=wfday4&role=attend
Puedes seguir la cuenta del evento aqui: clip_image006

Happy Coding!

lunes, 22 de noviembre de 2010

Host-named SiteCollections

En esta ocasión quiero hablar un poco acerca de los Host-Named SiteCollections (ó host-headers sitecollections). Que son, para que se utilizan, cuando no usarlos y como crearlos.


¿Que son los Host-Named SiteCollections?

Es la capacidad que brinda la infraestructura de SharePoint para crear SiteCollections, con lo que los amigos norteamericanos gustan nombrar como “vanity urls”. Es decir la capacidad de crear SiteCollections con un host-header personalizado e independiente de la url de la aplicación web, por ejemplo, consideremos las siguientes urls de sitecollections.

http://sales.contoso.com/
http://team.development.com/
http://research/

Si intentáramos utilizar el método de Path-based SiteCollection para formar estas urls, no nos quedaría más remedio que crear cada uno de estos sitecollection en una web application diferente para permitir que cada sitecollection tenga la url que se requiere.

¿Qué problema resuelven los Host-Named SiteCollections?

Gracias a esta característica podemos crear sitecollections con las urls que antes vimos, y todas vivir en una misma web application, sin necesidad de crear una web application independiente solo para resolver el tema de la url.

¿Para qué se utilizan los Host-Named SiteCollections?

Como comentamos antes, el uso principal es proveer la habilidad de nombrar sitecollections con una url que no tiene que ver en nada con la url de la web application en la cual vive.

Tiene un uso muy extendido en el área de hosting empresarial, o sea las empresas que se dedican a proveer hospedaje de sitios SharePoint, y es que, por medio de esta característica pueden construir una solución altamente escalable, ya que basta con crear una sitecollection con una url específica y asignar esa url a una entrada particular en sus DNS’s.

Otro uso es claramente, cuando una organización quiere dar identidad propia a cada una de sus áreas y/o suborganizaciones, y esto lo refleja en cada uno de los sitios de las mismas, que no solo tienen un aspecto visual distinto sino también una url única y acorde a sus funciones.

¿Cómo crear Host-Named SiteCollections?

Al igual que en la versión anterior, solo se pueden crear host-named sitecollections a través scripting, para generar los sitecollections antes mencionados podemos usar el siguiente script de ejemplo.

$web=Get-SPWebApplication http://sp2010:5300/

New-SPSite "http://sales.contoso.com" -OwnerAlias "moss\administrator" -HostHeaderWebApplication $web -Template "STS#0"

New-SPSite "http://team.development.com" -OwnerAlias "moss\administrator" -HostHeaderWebApplication $web -Template "STS#0"

New-SPSite "http://research" -OwnerAlias "moss\administrator" -HostHeaderWebApplication $web -Template "STS#0"


Ventajas y Desventajas

Como un buen amigo dice, todo siempre es un trade-off, y este tema no sería la excepción. Algunas de las desventajas de usar esta características versus usar el tradicional path-based sitecollections son:

Desventajas
  • No soportan AAM (Alternate Access mappings)
  • Se consideran siempre en la zona Default, por lo que no pueden responder a dos o más urls diferentes.

Ventajas:
  • Alta escabilidad en soluciones de hosting
  • Url personalizadas

Mención especial merece el hecho de que, por residir varios sitecollections en una misma web application, se comparte el web.config, esto es una ventaja o desventaja según se quiera o no compartir/aislar funcionalidad entre los sitecollections

Por último quisiera mencionar una utilería creada por Sharad Kumar, para agregar a la interfaz del sitio central de administración una opción para crear estos host-named sitecollections de manera visual



Recursos Adicionales:

domingo, 21 de noviembre de 2010

Configuración SharePoint 2010 - User Profile Application Service Error

Uno de los tantos errores que podemos obtener al intentar configurar el nuevo servicio de aplicación para perfiles de usuario(User Profile Application Service), al querer acceder a la página de administración de este servicio nos aparece este mensaje:

Y al revisar los logs de SharePoint encontramos una entrada como la siguiente:
UserProfileServiceUserStatisticsWebPart:LoadControl failed, Exception: System.IO.FileLoadException: The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) at Microsoft.Office.Server.UserProfiles.UserProfileConfigManager.InitializeIlmClient(String ILMMachineName, Int32 FIMWebClientTimeOut)
at Microsoft.Office.Server.UserProfiles.UserProfileConfigManager..ctor(UserProfileApplicationProxy userProfileApplicationProxy, Guid partitionID)
at Microsoft.SharePoint.Portal.WebControls.UserProfileServiceStatisticsWebPartBase.LoadControl(Object sender, EventArgs e)
Y es que he de admitir que si bien es cierto que este servicio sufrió grandes modificaciones y adiciones de nuevas características para la versión 2010, también es cierto que se volvió más difícil de configurar, administrar, y diagnosticar al momento de implementarlo. Y no difícil por la cantidad de pasos o procedimientos que se tienen que ejecutar, sino por la cantidad de errores con que nos podemos encontrar al intentar hacerlo trabajar.

Sin embargo este error, en especial, es muy conocido y fácil de solucionar. El escenario en el que se presenta muy usualmente es el siguiente.

Escenario
El servicio User Profile Application Service y el Sitio Central de Administración han sido provisionados en el mismo servidor.

Solución
Ejecute un IISRESET después de iniciar el servicio, eso es todo!.

lunes, 15 de noviembre de 2010

Desarrollo SharePoint 2010 - The Web application at [Url] could not be found

El siguiente es un error que aparece con mucha frecuencia  cuando comenzamos a desarrollar para SharePoint 2010, por lo menos esa es mi impresión en los equipos de desarrollo en que he participado.


The Web application at [Url] could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.
La excepción se presenta cuando accedemos programáticamente a un sitio SharePoint ("http://sp2010"), obviamente después de habernos asegurado que la url esta correcta.

Y es que sí creamos algún proyecto desde las plantillas de proyecto que vienen por default en Visual Studio 2010 especiales para desarrollo SharePoint, como lo son "Visual Web Part", "List Definition", "Sequential Workflow", etc. no obtendremos este error.


Sin embargo si creamos, por ejemplo, una aplicación de consola ó Windows Forms y después de agregar las referencias necesarias para trabajar con la API de SharePoint, muy probablemente nos aparecerá este error. Y esto es debido a que este tipo de aplicaciones al crearse especifican el valor de configuración de Platform target a x86, lo que indica que nuestra aplicación intentara ejecutarse como un proceso de 32 bits.

Para solucionar ó prevenir este comportamiento solo se debe establecer este valor de configuración a x64 ó Any CPU(si estamos desarrollando en un ambiente x64) y nuestro código funcionará correctamente.

Por cierto, no se olviden de establecer el parámetro de configuración Target framework a: .Net Framework 3.5

Recursos adicionales:
Visual Studio .NET Platform Target Explained

Happy Coding!

lunes, 11 de octubre de 2010

SharePoint DisableLoopbackCheck security feature

Hace unos días algunos desarrolladores me comentaban acerca de un "error" que ellos describían de la siguiente manera: "No podemos ver ninguna de los sitios SharePoint en el Servidor".

El problema

Cada vez que intentaban ver alguno de los sitios SharePoint, que se habían creado previamente, les pedía en repetidas ocasiones (las tres de rigor) su usuario y contraseña antes de mandar un error 401.1 Access Denied y una entrada en el EventViewer, todo esto solo cuando accedían a alguno de los sitios desde el servidor, desde cualquier cliente todo funcionaba correctamente.



Consideraciones a tomar

En primera instancia esto no es un gran problema porque ningún usuario usa alguno de los servidores de la granja de SharePoint para ver los sitios ahí hosteados. Pero y si es un servidor de pruebas? ó si ese servidor del que hablamos es nuestro entorno de desarrollo?. En estos casos es obligatorio que podamos acceder a los sitios sin que este comportamiento ocurra.

Un poco de historia

Este característica de seguridad fue introducida desde el Service Pack 1 de Windows Server 2003 y está presente hasta las versiones actuales de Windows Server 2008 R2. Básicamente lo que hace es bloquear el acceso a una web application usando el FQDN, si esto sucede la característica entra en acción y bloquea este acceso enviando un error 401.1, que por cierto no es muy adecuado.

¿Por qué se introdujo esta característica? Pues porque existían varios ataques que se basaban en reflección para engañar a IE y hacerle creer que se estaba trabajando de manera local y así burlar muchas restricciones de seguridad.

Algunos otros escenarios

Otros escenarios en los que esta característica de seguridad puede causar problemas, es en los servidores que además de tener el rol de WFE, también tienen el rol de Index. Esto porque básicamente el servidor Index intenta hacer un crawling (peticiones http) a sí mismo. Este comportamiento es fácilmente detectable porque los logs de crawling muestran cientos de errores del tipo 401.

Las soluciones

Pues muy fácil, seguimos las instrucciones del Microsoft's KB article 896861. Pero entonces para que todo este rollo que acaban de leer?

La solución dependerá en gran medida de lo que quieran hacer y el entorno en el que se encuentren. Como comentaba anteriormente, si se trata de un servidor de pruebas o de desarrollo, adelante!! Sigan el artículo y deshabiliten la característica LoopBackCheck.

Pero en un servidor productivo esto no es aceptable, ya que se constituye en un hueco de seguridad importante. Pero entonces, no es posible solucionar este problemilla en un servidor productivo? Por supuesto que sí!, sin embargo la solución no va por el camino de deshabilitar la característica LoopBackCheck, lo ideal es utilizar el Método dos descrito en el KB 896861, el cual indica la forma de agregar una entrada en el registro llamada BackConnectionHostNames, dentro de esta nueva entrada se agregarán host names que serán excluidos del funcionamiento de esta característica.




Algunas referencias adicionales

DisableLoopbackCheck?  Lets do it the right way
Groundhog Day: Configuring Back Connection Host Names using Group Policy
Setting Back Connection Host Names for SharePoint 2007 Using STSADM
You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version

jueves, 5 de agosto de 2010

The list cannot be displayed in Datasheet view with Office 2010

Si aún están utilizando Office 2007, y están intentado ver la vista de hoja de datos (datasheet view) de una lista que se encuentre en un sitio de SharePoint 2007, este artículo puede resolver su problema.

Sin embargo, si ustedes como yo, están utilizando ya Office 2010 e intentan acceder a su vieja intranet corporativa(por poner un ejemplo), desplegada sobre SharePoint 2007, podrían obtener también este error.
La solución a este pequeño inconveniente es instalar el 2007 Office System Driver: Data Connectivity Components, tal como refiere el KB 2266203.

Y con este sencillo paso, ahora ya podrán abrir las listas de SharePoint 2007 en modo "datasheet view" aún cuando no tengan instalado Office 2007 y si el poderoso Office 2010.

domingo, 25 de julio de 2010

[SharePoint Error] - An exception of type Microsoft.SharePoint.Upgrade.SPUpgradeException was thrown

Una excepción muy rara y un poco fuera de lugar, dado que no estaba ejecutando algún proceso de migración, como se podría suponer por el nombre y descripción del error.
Failed to create the configuration database.
An exception of type Microsoft.SharePoint.Upgrade.SPUpgradeException was thrown. Additional exception information: One or more types failed to load. Please refer to the upgrade log for more details.
Microsoft.SharePoint.Upgrade.SPUpgradeException: One or more types failed to load. Please refer to the upgrade log for more details.
at Microsoft.SharePoint.Upgrade.SPDelegateManager.RegisterAssembly(Assembly asm, UInt32 nOrder)
at Microsoft.SharePoint.Upgrade.SPDelegateManager.get_InitialTypeDictionary()
at Microsoft.SharePoint.Upgrade.SPDelegateManager.GetDelegateTypes(Type tpObject)
at Microsoft.SharePoint.Upgrade.SPDelegateManager.GetDelegates(Object o)
at Microsoft.SharePoint.Upgrade.SPDelegateManager.GetUpgraders(Object o)
at Microsoft.SharePoint.Upgrade.SPManager.NeedsUpgradeFalse(Object o)
at Microsoft.SharePoint.Administration.SPPersistedUpgradableObject.set_NeedsUpgrade(Boolean value)
at Microsoft.SharePoint.Administration.SPPersistedObject.Update()
at Microsoft.SharePoint.Administration.SPFarm.Update()
at Microsoft.SharePoint.Administration.SPConfigurationDatabase.RegisterDefaultDatabaseServices(SqlConnectionStringBuilder connectionString)
at Microsoft.SharePoint.Administration.SPConfigurationDatabase.Provision(SqlConnectionStringBuilder connectionString)
at Microsoft.SharePoint.Administration.SPFarm.Create(SqlConnectionStringBuilder configurationDatabase, SqlConnectionStringBuilder administrationContentDatabase, IdentityType identityType, String farmUser, SecureString farmPassword)
at Microsoft.SharePoint.Administration.SPFarm.Create(SqlConnectionStringBuilder configurationDatabase, SqlConnectionStringBuilder administrationContentDatabase, String farmUser, SecureString farmPassword)
at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.CreateOrConnectConfigDb()
at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.Run()
at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()

Por el contrario, estaba alegremente instalando MOSS 2007 SP2 en una máquina virtual.

Después de un rato de buscar en la red, solo se hace referencia en esta entrada de Microsoft Connect. Que menciona que si tienes instalado Office 2010 se puede presentar este problema, y en mi caso así fué. Una vez que desinstale Office 2010 y posteriormente procedí a reintentar la instalación de MOSS 2007, esta se ejecuto sin problemas.

Espero esta información les sea de utilidad.

domingo, 18 de julio de 2010

Exámenes para SharePoint 2010 liberados!

Si, los exámenes para SharePoint 2010 han sido liberados oficialmente el pasado 12 de julio, con el anuncio realizado en el blog Born to Learn.


The newest members of the SharePoint exam family are now available! 
70-573 -- TS: Microsoft SharePoint 2010, Application Development
70-576 -- PRO: Designing and Developing Microsoft SharePoint 2010 Applications
70-667 -- TS: Microsoft SharePoint 2010, Configuring
70-668 -- PRO: SharePoint Server 2010, Administrator

The links will take you the official exam pages with audience profiles, skills measured, and other information to help you prepare. 
Just getting started with SharePoint 2010? Find out more about upcoming training releases and other support from MS Learning here:

All four exams are available now in English at Prometric test centers worldwide.  Localized versions (Japanese, German, French and Brazilian Portuguese) are in the works and will be ready in early August.

martes, 22 de junio de 2010

[Webcast] - Configurar Alternate Access Mappings en SharePoint 2010

Tal y como dice el título de este post, aquí dejo un webcast en el que explico y muestro como configurar los AAM (Alternate Access Mappings) en SharePoint 2010.



Recuerden eston tres sencillos pasos:

  1. Agregar la Url de acceso alternativo en alguna de las zonas de nuestra web application.
  2. Agregar una entrada en su respectivo servidor de DNS, con el hostheader a utilizar.
  3. Agregar un binding en el IIS utilizando el hostheader antes mencionado, aunque no lo menciono en el webcast, este paso se debe ejecutar en cada uno de los WFE's :(

Recursos adicionales:
Some AAM guidance from the front lines
Server Name Mapping and Alternate Access Mapping (AAM)


sábado, 12 de junio de 2010

[Screencast] - Bloquear tipos de archivos en SharePoint 2010

Aquí les dejo un pequeño screencast en el que se ilustra el proceso para bloquear tipos de archivos en SharePoint 2010.  Adicionalmente, aquí pueden consultar la lista de extensiones de archivos que estan bloqueadas por defecto en SharePoint 2010


viernes, 28 de mayo de 2010

[Sharepoint Error] - Internet Information Services is not installed.

Internet Information Services is not installed. You must have Internet Information Services installed in order to use the SharePoint Products and Technologies Configuration Wizard


Sí alguna vez han obtenido este error al momento de instalar SharePoint 2007 sobre Windows Server 2008 R2, la solución es sumamente sencilla. Solo se necesita agregar el servicio "IIS Management Compatibility" al role de "Web Server IIS". ¿Y que como se hace esto?. A continuación descrito con imágenes.


viernes, 14 de mayo de 2010

SharePoint 2010 SDK y Language Pack's

Justo lo que dice en el título amigos míos, ya está disponible para su descarga el SDK de SharePoint 2010, asi como el language pack para SharePoint Foundation y el language pack para SharePoint 2010.

La mecánica de instalación de los paquetes de idiomas es la misma que la descrita en mi post anterior:  Instalando Language Pack's en SharePoint 2010

Sin duda, recursos de básicos para conocer a fondo SP 2010.

jueves, 13 de mayo de 2010

Propiedad CustomProperty del PeoplePicker

Una vez que ya sabemos cómo extender la funcionalidad del peoplepicker. Hay un tópico que es de mucha utilidad para darle mayor poder a nuestro control.

¿Qué pasa si queremos enviarle un dato a nuestro control para utilizarlo dentro la lógica de recuperación, filtrado y presentación de datos?

Pues en estos casos existe la propiedad CustomProperty de tipo string que heredamos de EntityEditorWithPicker, y que podemos utiizar para propósitos diversos.

Escenario:
En mi caso, yo necesitaba excluir a algunos usuarios (sin ninguna relación preestablecida). Por lo que al instanciar el control CustomPeoplePicker asignaba en una cadena separada por comas, los usuarios que no podían ser seleccionados en el control.

protected override void CreateChildControls()
{
 if (!_error)
 {
  try
  {

   base.CreateChildControls();
   Blog.WebControls.CustomPeoplePicker picker = new Blog.WebControls.CustomPeoplePicker();
   picker.CustomProperty = "juan.topo@contoso.com";
   picker.ID = "customPicker1";

   // Your code here...
   this.Controls.Add(picker);
  }
  catch (Exception ex)
  {
   HandleException(ex);
  }
 }
}

Acto seguido recuperaba la propiedad en el método OnLoad de la clase CustomPickerDialog que deriva de PickerDialog.

protected override void OnLoad(EventArgs e)
 {
  CustomQueryControl control = (CustomQueryControl)this.QueryControl;
  control.ExcludedUsers = this.Page.Request.QueryString["CustomProperty"];
  base.OnLoad(e);
 }
Como se puede observar, el parámetro que establecimos previamente, es pasado en el querystring hacia el PickerDialog con el key "CustomProperty". Una vez recuperado podemos asignarlo a alguna propoedad propia para ser utilizada posteriormente.



Dejo el codigo completo de la solución para mayor referencia.



Happy coding!

miércoles, 12 de mayo de 2010

Tercer Simposio Latinoamericano de SharePoint en México









Si, de nuevo este año se llevará a cabo el Simposio latinoamericano de SharePoint en México, (el tercero). Por lo que es de mi mayor agrado invitarlos a que asistan y conozcan un poco más de las nuevas caracteristicas que vienen en SP 2010.

Me permito citar la información proporcionada en el blog de Luis Du Solier.

SharePoint 2010, La nueva plataforma de productividad para la empresa y la Web

La Comunidad de SharePoint México y Microsoft, te invitan al tercer Simposio Latinoamericano de SharePoint en la Ciudad de México. En este evento contaremos con grandes expositores de Latinoamérica y de Estados Unidos quienes compartirán con nosotros las mejores prácticas y recomendaciones así como las ventajas y beneficios de la versión de SharePoint 2010

La cita es

Fecha: jueves 3 de junio

Lugar: Hacienda de los Morales

Dirección: Vázquez de Mella 525 Col. Del Bosque, Polanco, 11510 México D.F.
Tel. (55) 5283 30 54 / 55

Horario: 8 am a 8 pm (por la mañana Developers, tarde IT Pro). Les invitamos a que lleguen a partir de las 8 de la mañana para el registro (no olviden llevar sus hojas de registro)

Consulta la agenda y Regístrate aquí

jueves, 6 de mayo de 2010

Extendiendo el control PeoplePicker

Ahora presentaré un pequeño ejemplo de cómo se puede extender el control People Picker, que tanto gusta a los usuarios, pero que en ciertos escenarios (siempre habrá un usuario anormal) no satisface los requerimientos funcionales al cien por ciento, lo que nos llevará irremediablemente a tirar código.

Al final de esta demostración nos daremos cuenta que al extender este control podemos realizar búsquedas sobre diferentes objetos y/o diferentes fuentes de datos, porque este control no está casado con objetos de tipo SPUser como se podría pensar en primera instancia.

Sin más, pasemos al código.Para poder extender la funcionalidad de este control, basicamente tenemos que heredar de tres clases: EntityEditorWithPicker, PickerDialog y SimpleQueryControl.

Dejemos que el código se explique solo :)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Collections;
using Microsoft.SharePoint;

namespace Blog.WebControls
{
    public class CustomPeoplePicker : EntityEditorWithPicker
    {
        protected bool m_onInitCalled;
        protected string m_commaSeparatedAccountsDelayedUntilOnInit;

        public CustomPeoplePicker()
        {

        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            //definimos el tipo del PickerDialog
            this.PickerDialogType = typeof(CustomPickerDialog);

            this.m_onInitCalled = true;

            if (!string.IsNullOrEmpty(this.m_commaSeparatedAccountsDelayedUntilOnInit))
            {
                base.UpdateEntities(this.GetAccountsEntities(this.m_commaSeparatedAccountsDelayedUntilOnInit));
                this.m_commaSeparatedAccountsDelayedUntilOnInit = null;
            }
        }

        /// 
        /// Devuleve la lista de usuarios seleccionados en forma de cadena
        /// 
        ///         /// 
        private string GetResolvedEntityAccounts()
        {
            if (this.ResolvedEntities == null)
            {
                return string.Empty;
            }
            if (this.ResolvedEntities.Count == 0)
            {
                return string.Empty;
            }

            List names = new List();
            string list = string.Empty;
            foreach (PickerEntity entity in this.ResolvedEntities.OfType())
            {
                names.Add(entity.Key);
            }
            list = string.Join(this.EntitySeparator.ToString(), names.ToArray());
            return list;
        }

        protected ArrayList GetAccountsEntities(string commaSeparatedAccounts)
        {
            ArrayList list = new ArrayList();
            if (commaSeparatedAccounts != null)
            {
                foreach (string str in commaSeparatedAccounts.Split(new char[] { this.EntitySeparator }, StringSplitOptions.RemoveEmptyEntries))
                {
                    string str2 = str.Trim();
                    if (!string.IsNullOrEmpty(str2))
                    {
                        PickerEntity entity = new PickerEntity();
                        entity.Key = str2;
                        list.Add(entity);
                    }
                }
            }
            return list;
        }

        /// 
        /// Valida las entidades
        /// 
        ///         /// 
        public override PickerEntity ValidateEntity(PickerEntity needsValidation)
        {
            needsValidation.IsResolved = false; ;

            CustomQueryControl c = new CustomQueryControl();
            foreach (CustomUser user in c.GetPeople())
            {
                if (needsValidation.Key.Equals(user.EmployeeNumber, StringComparison.InvariantCultureIgnoreCase))
                {
                    needsValidation.IsResolved = true;
                }
            }
            return needsValidation;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Collections;

namespace Blog.WebControls
{
    public class CustomPickerDialog : PickerDialog
    {
        public CustomPickerDialog()
            : base(new CustomQueryControl(), new TableResultControl(), new CustomPeoplePicker())
        {
            ArrayList columnDisplayNames = ((TableResultControl)base.ResultControl).ColumnDisplayNames;
            columnDisplayNames.Clear();
            columnDisplayNames.Add("Employee Number");
            columnDisplayNames.Add("Email");
            columnDisplayNames.Add("Name");
            
            ArrayList columnNames = ((TableResultControl)base.ResultControl).ColumnNames;
            columnNames.Clear();
            columnNames.Add("EmployeeNumber");
            columnNames.Add("Email");
            columnNames.Add("Name");
            
            ArrayList columnWidths = ((TableResultControl)base.ResultControl).ColumnWidths;
            columnWidths.Clear();
            columnWidths.Add("20%");
            columnWidths.Add("30%");
            columnWidths.Add("50%");
        }
        protected override void OnLoad(EventArgs e)
        {
            CustomQueryControl control = (CustomQueryControl)this.QueryControl;
            base.OnLoad(e);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Data;

namespace Blog.WebControls
{
    public class CustomQueryControl : SimpleQueryControl
    {
        public CustomQueryControl()
        {
            Load += CustomQueryControl_Load;
        }

        void CustomQueryControl_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                EnsureChildControls();
                mColumnList.Items.Add("EmployeeNumber");
                mColumnList.Items.Add("Name");
                mColumnList.Items.Add("Email");
            }
        }

        protected override int IssueQuery(string search, string groupName, int pageIndex, int pageSize)
        {
            CustomUser[] usersAux = this.GetPeople();
            if (usersAux == null)
                return 0;
            List allPeople = new List(usersAux);
            if (allPeople.Count == 0)
                return 0;

            List searchPeople = new List();
            DataTable resultTable = null;

            searchPeople = allPeople;

            if (groupName == "Name" && !string.IsNullOrEmpty(search))
            {
                searchPeople = allPeople.Where(x => SearchString.Match(x.Name, search)).ToList();
            }
            else if (groupName == "Email" && !string.IsNullOrEmpty(search))
            {
                searchPeople = allPeople.Where(x => SearchString.Match(x.Email, search)).ToList();
            }

            resultTable = GetPeopleTable(searchPeople.ToArray());

            PickerDialog.Results = resultTable;
            PickerDialog.ResultControl.PageSize = resultTable.Rows.Count;

            return resultTable.Rows.Count;
        }

        private DataTable GetPeopleTable(CustomUser[] people)
        {
            DataTable dummyTable = new DataTable();
            dummyTable.Columns.Add("EmployeeNumber");
            dummyTable.Columns.Add("Name");
            dummyTable.Columns.Add("Email");

            foreach (CustomUser person in people)
            {
                DataRow row1 = dummyTable.NewRow();
                row1["Name"] = person.Name;
                row1["EmployeeNumber"] = person.EmployeeNumber;
                row1["Email"] = person.Email;
                dummyTable.Rows.Add(row1);
            }
            return dummyTable;
        }

        string _excludedUsers;

        public string ExcludedUsers
        {
            get
            {
                return this._excludedUsers;
            }
            set
            {
                this._excludedUsers = value;
            }
        }

        public virtual CustomUser[] GetPeople()
        {
            List people = new List();

            //agregar toda la logica necesaria para obtener los usuarios
            people.Add(new CustomUser() { EmployeeNumber = "11111", Email = "juan.topo@contoso.com", Name ="Juan G. Topo" });
            people.Add(new CustomUser() { EmployeeNumber = "22222", Email = "max.power@contoso.com", Name = "Max Power" });
            people.Add(new CustomUser() { EmployeeNumber = "33333", Email = "bambi.venado@contoso.com", Name = "Venado Bambi" });
            people.Add(new CustomUser() { EmployeeNumber = "44444", Email = "homero.simpson@contoso.com", Name = "Homero J. Simpson" });

            return people.ToArray();
        }

        public override PickerEntity GetEntity(DataRow dr)
        {
            PickerEntity entity = new PickerEntity();
            entity.DisplayText = dr["Name"].ToString();
            entity.Key = dr["EmployeeNumber"].ToString();
            entity.Description = dr["Email"].ToString();
            entity.IsResolved = true;
            return entity;
        }
    }
}


Happy Coding!

domingo, 25 de abril de 2010

[Screencast] - Instalando Language Pack's en SharePoint Server 2010

El dia de hoy mostraré en un corto pero sustancioso screencast como instalar el language pack correspondiente al idioma español para SharePoint Server 2010. La posterior instalación de cualquier otro language pack se realiza de la misma manera.

Los language packs debes ser instalados en todos y cada uno de los WFE’s (web front end) de nuestra granja de servidores. Como se aprecia en el video, para granjas que estén ejecutando SharePoint Server 2010, es necesario primero instalar el language pack correspondiente a SharePoint Foundation 2010, muy a la manera de SharePoint 2007, en donde primero debíamos instalar el language pack de WSS 3.0 y posteriormente el de MOSS. A continuación los pasos a seguir:


Instalación del language pack de Español de SharePoint Foundation 2010

  1. Ejecutar el archivo SharePointLanguagePack.exe.
  2. Leer detenidamente el contrato de licencia y aceptar los términos
  3. Una vez que el asistente termine, hacer click en cerrar para que se ejecute el asistente para la configuración de Productos y tecnologías de SharePoint.
  4. Cuando el asistente se inicie hacemos click en Next para continuar
  5. Aparecerá una ventana indicándonos que algunos servicios podrían ser re-iniciados durante la configuración, es estrictamente necesario que hagamos click en Yes, por lo que les recomiendo que calendaricen este proceso en un horario adecuado, para ambientes productivos.
  6. Se iniciara el proceso de configuración de SharePoint, damos click en Finish y se abrirá el sitio Central de Administración, con esto el language pack de español para SharePoint Foundation ha sido instalado y configurado correctamente


Instalación del language pack de Español de SharePoint Server 2010

  1. Ejecutar el archivo ServerLanguagePack_es-es.exe (para el caso de español).
  2. Leer detenidamente el contrato de licencia y aceptar los términos
  3. Una vez que el asistente termine, hacer click en cerrar para que se ejecute el asistente para la configuración de Productos y tecnologías de SharePoint.
  4. Cuando el asistente se inicie hacemos click en Next para continuar
  5. Aparecerá una ventana indicándonos que algunos servicios podrían ser re-iniciados durante la configuración, es estrictamente necesario que hagamos click en Yes, por lo que les recomiendo que calendaricen este proceso en un horario adecuado, para ambientes productivos.
  6. Se iniciara el proceso de configuración de SharePoint, damos click en Finish y se abrirá el sitio Central de Administración, con esto el language pack de español para SharePoint Server 2010 ha sido instalado y configurado correctamente


Además de lo anterior, en el screencast se puede apreciar como después de este proceso, cuando creemos un nuevo SiteCollection, en la página de creación nos aparecerá una nueva opción en la cual podemos seleccionar el lenguaje de nuestro SiteCollection.



Y por último, pero no menos importante, se muestra cómo podemos habilitar idiomas alternativos, para que el sitio pueda ser visto en otro idioma, del conjunto de los que se tienen instalados en la granja, en este caso Ingles y Español. Obviamente lo anterior está sujeto a que el contenido que se despliega este regionalizado (no existe la magia en SharePoint).






Espero que este screencast les sea de utilidad

lunes, 15 de marzo de 2010

[Screencast] - Cambiar un sitio de SharePoint de Puerto

En alguna implementación que hice hace ya tiempo, ocurrió un malentendido al designar el puerto en el que estaría hosteado la aplicación en el ambiente de producción. El sitio fue creado sobre el puerto 1070(por ejemplo), mientras que el usuario esperaba que este fuera creado en el puerto 80, para que con esto, el pudiera acceder a través de una url amigable, tal como http://moss en vez de http://moss:1070.

Alguna de las alternativas posibles para la corrección de este pequeño error, serian la creación de un AAM ó hacer un backup y posteriormente un restore de la base de datos de contenido en otro sitio.

Sin embargo, existe otra forma, más limpia (a mi parecer), para lograr el cambio de puerto de un aplicación SharePoint.

La solución propuesta

Lo que tenemos que hacer es, desextender (que fea palabra) la aplicación, para posteriormente extenderla en el puerto que nosotros deseemos. Como siempre, esto podemos hacerlo de manera grafica por medio del sitio de administración central. Para lo cual he creado un screencast en el que se observa como hacerlo.




Además de que también proporciono la forma de hacerlo mediante la utilería stsadm.

stsadm –o unextendvs –url http://moss:1070 -deleteiissites
stsadm –o extendvsinwebfarm –url http://moss –vsname “Portal MOSS”

Espero este tip les sea útil.

lunes, 15 de febrero de 2010

[SharePoint 2007] An unrecognized HTTP status was received. Check that the address can be accesed using Internet Explorer.

Después de una implementación sin mayores problemas, y tras dos meses de que había estado funcionando correctamente. Un buen día me doy cuenta que el rastreo no está funcionando y me está devolviendo miles (literalmente) de errores como los siguientes.


Lo primero que uno piensa es que la cuenta con la que se está intentando hacer el rastreo, no tiene permisos para ejecutarlo. Sin embargo la cuenta si tiene los permisos necesarios, es más, tal como dice el mensaje de "ayuda", intento acceder a algunas de las url's a las cuales supuestamente no puede acceder, y para mi sorpresa (si, aún me sorprendo con los errores de SharePoint), el navegador si es capaz de abrir esta url.

He aquí cuando de verdad comienza mi desconcierto, si la cuenta de acceso para el rastreo si puede acceder a las fuentes de contenido, y además mediante el navegador es posible acceder a ese contenido, que otra cosa puede ser?

Pues después de mucha investigación y leer artículos de mucha ayuda como: What every SharePoint administrator needs to know about Alternate Access Mappings (Part 2 of 3)

La causa y la resolución de la misma es un poco rebuscada.

1.- Elimina el proxy establecido de los servidores desde donde no se puede tener acceso y al servidor de destino, es decir el servidor con el rol de Index, y los WFE. No importa que el proxy sea establecido a través de alguna política. Si tienes seleccionado el checkbox de "Automatically detect settings", deselecciónalo.



2.- Deseleccionar la opción "Append parent suffixes of the primary DNS Suffix." Esto lo puedes hacer con los siguientes pasos:

Ve al Panel de Control
Entra al apartado de Network Connections
Click derecho sobre tu conexión, en mi caso (Local Area Connection), click en properties
Selecciona Internet Protocol Version 4 (TCP/IPv4)
Click en Properties
En la siguiente ventana click en Advanced
En la siguiente ventana seleccionamos el tab de DNS
Deselecciona la opción Append parent suffixes of the primary DNS Suffix




Información Adicional:

http://support.microsoft.com/kb/938219
What every SharePoint administrator needs to know about Alternate Access Mappings (Part 2 of 3)

lunes, 8 de febrero de 2010

[Screencast] Error al abrir SharePoint Solution Generator 2008

Es común que cuando instalamos por primera vez las extensiones de Visual Studio para WSS (vsewss 1.3) en Windows 2008 Server, se nos presente el siguiente error al querer utilizarlo.


The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: ...

Como sabemos estas extensiones al instalarse crean un web application en el IIS llamado VSeWSS, que contiene un servicio con extensión .svc (Windows Communication Service), el cual para su correcto funcionamiento necesita de la habilitación de la característica WCF HTTP Activation. Así que para solucionar este pequeño inconveniente solo es necesario habilitar esta característica. Con los siguientes pasos:

  • Abre la consola de administración del servidor (Server Manager)
  • Ve a la pestaña de Features
  • Click en Add Features
  • Expande el nodo llamado .Net Framework  3.0 Features
  • Expande el nodo WCF Activation
  • Selecciona la opción HTTP Activation. La opción Non-HTTP Activation no es requerida para este propósito.
  • Click en Next
  • Click en Install

Después de completar estos sencillos pasos, la utileria SharePoint Solution Generator 2008, funcionará correctamente.


Dejo además un screencast en donde se muestra de manera gráfica los pasos anteriormente descritos.



Happy Coding!

lunes, 1 de febrero de 2010

[Sharepoint 2010] - SharePoint Client Object Model

Pues comenzamos con los posts relacionados con SharePoint 2010, en cuanto a desarrollo se refiere, específicamente con el SharePoint Client Object Model (SharePoint OM). En esta ocasión revisaremos la teoría previa, que problema resuelve y como funciona.

En el pasado (en realidad presente para la mayoría de nosotros), cuando construimos alguna aplicación cliente (como Silverlight) que se integraría con SharePoint 2007, lo hacíamos a través de web services, ya sea que usaramos los que SharePoint nos proporciona out the box ó que desarrolláramos los propios para satisfacer requerimientos puntuales de negocio.

Sin embargo esto no era del todo transparente, puesto que había que saber un par de cosillas adicionales de cómo funcionan los Web Services en SharePoint, máxime si nos decidíamos a utilizar WCF, quien no lanzo varios WTF's!, cuando descubrió la falla incapacidad de Sharepoint de convivir con los archivos .SVC.

¿Cuál es la solución que SharePoint 2010 nos brinda?

SharePoint 2010 Managed Client Object Model es una característica que nos permite escribir código del lado del cliente para trabajar con los objetos comunes con los que estamos acostumbrados a tratar del lado del servidor. Todo este código que se ejecuta del lado del cliente ahora puede agregar listas, actualizarlas, eliminarlas, manipular elementos de listas, manipular documentos que se encuentran el librerías, crear, eliminar y modificar sitios, y muchas cosas más, como veremos con forme pase el tiempo.


Además este nuevo modelo de objetos viene en tres diferentes sabores, para adaptarse a las necesidades del día a día de un desarrollador:

.Net Managed Applications (usando .NET CLR)
Silverlight Applications
ECMAScript (JavaScript, JScript)

Es importante es este punto hacer mención de que las clases del modelo de objetos en el cliente se les ha quitado el prefijo "SP", que tanto molestaba a algunos.

ServidorCliente
SPContextContext
SPWebWeb
SPSiteSite
SPListList
SPListItemListItem


Pero como aquel famoso programa de TV pregunta, ¿Y cómo funciona esto?

Nosotros interactuamos con la API en alguno de los sabores antes mencionado, es decir, llamamos métodos, asignamos propiedades, etc. Después de esto, nosotros hacemos una llamada al método ExecuteQuery ó ExecuteQueryAsync (este último para Silverlight), entonces el Client OM, se encarga de transformar todas esas operaciones que hicimos en un documento XML y enviarlo al servidor, por medio del servicio client.svc que expone SharePoint 2010. El servidor recibe la solicitud enviada desde el Client OM y hace las correspondientes llamadas a los objetos y métodos del modelo de objetos de servidor (si, si, SPContext, SPSite, SPWeb, etc.). Una vez que el servidor termine de procesar las operaciones solicitadas, este devolverá la respuesta serializada con JSON. El Client OM, recibe la respuesta y parsea el JSON a objetos .Net o bien a objetos javascript, en caso de que estemos utilizando ECMAScript.

void LoadData()
{
 ClientContext context = new ClientContext("http://mss:5300");
 Web web = context.Web;
 ListCollection lists = web.Lists;
 context.Load(web);
 context.Load(lists);

 context.ExecuteQueryAsync(succededCallback, failedCallback);
}


El servicio Client.svc


Mirando la respuesta enviada al cliente.

domingo, 31 de enero de 2010

[Silverlight] - Whitespace is not allowed after end of Markup Extension

Creo que muchos hemos obtenido en repetidas ocasiones este error al desarrollar aplicaciones Silverlight, y muchos de nosotros nos desconcertamos la primera vez que lo vimos, aunque ahora solo nos recuerde lo humanos que somos.

Pues bien, no pierdas la calma, este es un error muy tonto de sintaxis. Y se debe a que hemos dejado un espacio al final de una declaración de Binding dentro del markup. Como en la siguiente imagen:

Una vez que eliminemos éste espacio en blanco, el código compilará normalmente.

Happy Coding!

martes, 26 de enero de 2010

Descargar máquina virtual de SharePoint 2010

Así es, ya esta disponible para su libre descarga, una máquina virtual con SharePoint 2010, con la que podrémos probar las nuevas funcionalidades que nos brindará la siguiente versión de SharePoint.

Este es el link de donde pueden descargarla, en esta misma página podrán también descargar una máquina virtual para probar Office 2010, así que ya no hay excusas para no comenzar a utilizar estos dos productos.

Enjoy!

miércoles, 20 de enero de 2010

FREE! SharePoint 2010 eMagazine

Pues así es, amigos míos, se ha publicado al fin, una revista electrónica especializada a cerca de SharePoint 2010, creada por algunos de los expertos mas reconocidos en la comunidad.

Estos son algunos de los temas y autores de esta edición:

SharePoint 2010 Enterprise – Sjoerd van Lochem
Customizing the SharePoint Ribbon - Marianne van Wanrooij
Visual Studio Extensions - Niels Loup
Working with data in SharePoint Designer 2010- Laura Rogers
Sandboxed Solutions – Mirjam van Olst
New ECM features in SharePoint 2010 - Robert van Son
Creating new visual experiences with Visio Services - Toni Frankola
A SharePoint User eXperience - Sandra de Ridder
Introduction to the Business Connectivity Services – Nick Swan
SharePoint 2010 Client Object Models – Ton Stegeman
Understanding Identity in SharePoint 2010 - Michiel van Otegem
Happy Together in 2010! - Dux Raymond
SharePoint 2010 Chart Web Part - Agnes Molnar
Enrich your SharePoint 2010 portal by integrating SAP applications -
Cyrille Visser , Johan Kroese and Huub Montanus
SharePointComic - Dan Lewis

Sin duda, esta revista será una buena fuente de conocimiento para todos los entusiastas de SharePoint 2010

domingo, 10 de enero de 2010

Exception from HRESULT: 0x81070201

Este error suele suceder cuando estamos provisionando "Instancias de Listas" (ListInstance.xml), a partir de una definición previamente provisionada (ListTemplate.xml).

Básicamente existen dos posibilidades que pudieran ocasionar obtener este bonito error en SharePoint, las cuales son:



  1. Al momento de la activación de la feature (feature1.xml) que provisiona la instancia de la Lista, no se encuentra el archivo schema.xml, es decir, no encuentra la definición a partir de la cual creará la lista. Luego entonces, debemos asegurarnos de que el archivo schema.xml, sea correctamente provisionado y en la ruta correcta. Asegurense de incluir el archivo schema.xml utilizando el elemento <ElementFile/>
  2. Cometimos un error al momento de asignar el atributo Name del elemento ListTemplate, en el archivo ListDefinition.xml. Recuerden que este atributo debe establecerse con el mismo nombre que el del folder en donde se encuentra el archivo schema.xml (sin espacios).




Happy coding!

Etiquetas

SharePoint 2010 (38) Microsoft (32) Desarrollo SharePoint (31) Gerardo Reyes Ortiz (27) SharePoint (20) SharePoint 2013 (18) Errores SharePoint (12) México (10) PowerShell (9) Silverlight (8) Visio Services (7) Features (6) MVP (6) Silverlight 3 (6) WebCast (6) Workflows (6) Configuracion SharePoint 2010 (5) D.F. (5) API REST (4) Configuracion SharePoint 2010; (4) Troubleshooting (4) Visual Studio 2010 (4) Visual studio (4) WSS (4) Web parts (4) Apps (3) Comunidad SharePoint (3) Configuración SharePoint 2013 (3) ODATA (3) SharePoint Server (3) SharePoint; Instalación SharePoint; Troubleshooting; Search Service (3) Silverlight 3.0 (3) Silverlight Toolkit (3) WebParts (3) javascript (3) jquery (3) Eventos SharePoint (2) Office 2010 (2) PeoplePicker (2) REST (2) SQL Server (2) Scripting (2) Search Service Application (2) SharePoint Designer (2) UPA (2) UPS (2) Workflows SharePoint (2) host header (2) Apps Development (1) Big Bang (1) CAS (1) CSOM (1) Codeplex (1) CompartiMOSS (1) Configuracion SharePoint 2010; Errores SharePoint (1) Configuracion SharePoint 2010; SharePoint 2010 (1) Custom Actions (1) Custom Editor Parts (1) Delegate Controls (1) Deployment (1) DisableLoopbackCheck (1) Document Library (1) Entrevista (1) Examenes de Certificación (1) Extract WSP (1) FBA (1) FS4SP (1) Fakes (1) Fast Search Server 2010 For SharePoint (1) Fiddler (1) HTTP.SYS (1) HTTPS (1) JSON (1) Language Pack's (1) Latam (1) MAXDOP (1) MCSM (1) MSExpertos (1) MVC (1) Microsoft México (1) Microsoft; Codeplex; Screencast; (1) My Sites (1) SQL Server 2012 (1) SQL Server Reporting Services (1) Screencast (1) Screencast; (1) Service Applications (1) Service Pack (1) SharePoint 2007 (1) SharePoint 2010 SP 1 (1) SharePoint API (1) SharePoint Conference (1) SharePoint Emulators (1) SharePoint Farm (1) SharePoint Health Analyzer (1) SharePoint Magazine (1) SharePoint Online (1) SharePoint Search (1) SharePoint Test (1) SharePoint; Desarrollo SharePoint (1) Shims (1) Simposio (1) Simposio Latinoamericano (1) SkyDrive Pro (1) Soporte Microsoft (1) Templates (1) Tip (1) VSeWSS (1) Virtual Machine (1) Visual Studio 2012 (1) WCF (1) WSS; IIS 7 (1) Web API (1) Web Content Management (1) Web Services (1) Windows 8 (1) Windows Live ID (1) Xml (1) appcmd (1) iOS (1) jqGrid (1) onload function (1)