jueves, 8 de julio de 2010

No hay instancias de Servicio de perfiles de usuario iniciadas

Me encanta lo intuitivo y sorprendente que es SharePoint, hoy me he encontrado al entrar en la configuración de perfiles con el error:

"No hay instancias de Servicio de perfiles de usuario iniciadas en ningún servidor de este conjunto. Asegúrese de que al menos una instancia se inicia en un servidor de aplicaciones del conjunto de servidores mediante la página Servicios del servidor en la Administración central."

Al verificar que la instancia de servicio “Servicio de perfiles de usuario” estuviera iniciada (Administración central >  Administración de aplicaciones > Administrar servicios en el servidor), encontré con que no existía!!!.

Después de varias horas conseguí restaurarlo con los siguientes pasos:

  • Borré la aplicación de servicio de perfiles
  • Ejecuté el asistente de configuración de SharePoint 2010 (Menú inicio –> Microsoft SharePoint 2010 Products –> Asistente para la configuración de productos de SharePoint 2010). Lo intenté con el comando “psconfig.exe -cmd services -provision” pero me daba error.
  • Mediante el asistente de configuración cree una nueva aplicación de servicio de perfiles (Administración central > Asistentes de configuración > Inicia el Asistente de configuración del conjunto de servidores).
  • A continuación le di permisos de “Control total” a mi usuario administrador sobre la nueva aplicación de servicios y de lectura
  • Como ya aparecía la instancia de servicios la inicié (Administración central >  Administración de aplicaciones > Administrar servicios en el servidor).

Lo malo fue que perdí las configuraciones anteriores ya que no fui capaz de recuperar el servicio con las bases de datos anteriores :)

miércoles, 7 de julio de 2010

Acceso denegado por Conectividad a datos empresariales

Al utilizar el servicio de BCS (Business Connectivity Services) con un usuario no administrador puede que nos salte al cargar la página el error “Acceso denegado por Conectividad a datos empresariales”, si miramos el log de SharePoint encontraremos una traza similar a la siguiente:

Error while executing web part: Microsoft.SharePoint.SPException: Acceso denegado por Conectividad a datos empresariales. ---> Access Denied for User …

 

Este mensaje se debe a que el usuario logado en ese momento no tiene permisos para ejecutar los métodos definidos en BCS. Para solucionarlo entraremos en la Consola de Administración Central de SharePoint 2010 > Administración de aplicaciones > Administrar aplicaciones de servicio y buscaremos nuestra aplicación de servicio de BCS. Entraremos en su página de administración y pulsaremos en la opción “Establecer permisos del almacén de metadatos”:

image

A continuación, indicaremos los usuarios a los que queremos dar permisos y pulsaremos en “Agregar”. Seleccionaremos el usuario y marcaremos el permiso “Ejecutar”. Por último seleccionaremos el checkbox “Propague permisos a todos los modelos de BDC…” y aceptaremos los cambios.

image

[Tips SharePoint 2010]Actualizar ámbitos de búsqueda con PowerShell

Desde PowerShell (Consola de administración de SharePoint 2010) podremos forzar la actualización de los ámbitos de búsqueda de SharePoint sin entrar en la página de configuración del servicio:

$ssa = Get-SPenterpriseSearchServiceApplication
$ssa.StartScopesCompilation()

Si disponemos de más de una aplicación de servicio la obtendremos indicando el nombre en el parámetro –Identity: $ssa = Get-SPenterpriseSearchServiceApplication –Identity {Nombre aplicación de servicio}

martes, 6 de julio de 2010

Metadatos administrados: Modelo de objetos y controles (II)

Siguiendo con el post Metadatos administrados: Modelo de objetos y controles (I), veremos en esta ocasión cómo crear nuevas estructuras de metadatos y como consultar los elementos que estén asociadas a ellas mediante el modelo de objetos.

Creación de términos

Crearemos una estructura similar a la siguiente imagen:

image

Lo primero que haremos será hacer un “using Microsoft.SharePoint.Taxonomy;”, para conectar al servicio de metadatos obtendremos una referencia mediante “new TaxonomySession(site);”, a continuación agregaremos un código similar al siguiente:

public static void CrearTerminos()
{
            using (SPSite site = new SPSite("
http://UrlColecciónDeSitios"))
            {
                TaxonomySession session = new TaxonomySession(site);
                TermStore termStore = session.TermStores["Servicio de metadatos administrados"]; // Almacén de términos
                Group NuevoGrupo = termStore.CreateGroup("Grupo de Pruebas");
                NuevoGrupo.AddContributor("Dominio\\usuario");
                TermSet conjuntoDeTerminos = NuevoGrupo.CreateTermSet("Nuevo conjunto");
                int lcidSpanish = System.Globalization.CultureInfo.GetCultureInfo("es-ES").LCID;
                Term termino1 = conjuntoDeTerminos.CreateTerm("Término 1", lcidSpanish);
                Term termino2 = conjuntoDeTerminos.CreateTerm("Término 2", lcidSpanish);
                termStore.CommitAll();
            }
}

 

Mediante la propiedad TermStores obtenemos una referencia al almacén de metadatos sobre el que crearemos nuestra estructura. Con el método CreateGroup() crearemos un nuevo grupo de términos. Con CreateTermSet crearemos un nuevo conjunto de términos, si no indicamos nada en el segundo parámetro se creará para el idioma por defecto. Con el método CreateTerm() crearemos términos por debajo del grupo de términos o debajo de otros términos, el segundo parámetro indica el código lcid del idioma del término.

 

Consulta de términos

Una vez hayamos asociado los metadatos a nuestros contenidos podremos realizar consultas sobre ellos con el modelo de objetos, CAML y el motor de búsqueda.

 

Para obtener un término a partir de su descripción utilizaremos el método GetTerms():

public static void ObtenerTerminos()
{
            using (SPSite site = new SPSite("
http://UrlColecciónDeSitios"))
            {
                TaxonomySession session = new TaxonomySession(site);
                int lcidSpanish = System.Globalization.CultureInfo.GetCultureInfo("es-ES").LCID;
                TermSetCollection termSetColl= session.GetTermSets("Nuevo conjunto", lcidSpanish);
                TermCollection termColl = session.GetTerms("Término 1", true);
            }
}

 

Para realizar consultas con CAML nos encontraremos con que tendremos que realizar una serie de pasos adicionales ya que al agregar una columna de tipo “Metadatos administrados” SharePoint creará una columna oculta de tipo lookup para facilitar las búsquedas.

Tendremos que obtener entonces el identificador de la columna lookup para construir después la consulta CAML con una estructura similar a la siguiente:

<Query><Where><In><FieldRef LookupId="TRUE" Name="{Nombre interno de la columna a consultar}" /><Values><Value Type="Integer">{Id de la columna lookup de metadatos}</Value></Values></In></Where></Query>

 

El siguiente ejemplo muestra cómo obtener los elementos catalogados con el término “Automóvil” en una lista mediante CAML:

 public static void ObtenerElementosConTermino() 
{
            using (SPSite site = new SPSite("
http://UrlColecciónDeSitios"))
            {
                TaxonomySession session = new TaxonomySession(site);
                TermCollection termColl = session.GetTerms("Automóvil", true);
                foreach(Term term in termColl)
                {
                    if (term.IsKeyword)
                    {
                        int[] arIdsDeElementos = TaxonomyField.GetWssIdsOfKeywordTerm(site, term.Id, 1000);
                    }

                    int[] arIdsDeElementos2 = TaxonomyField.GetWssIdsOfTerm(site, term.TermStore.Id, term.TermSet.Id, term.Id, true, 1000);
                    using (SPWeb web = site.OpenWeb())
                    {
                        SPList listaDocumentos = web.Lists["Documentos generales"];
                        SPQuery queryCAML = new SPQuery();
                        StringBuilder sb = new StringBuilder();
                        foreach(int idLookup in arIdsDeElementos2)
                        {
                            sb.Append(string.Format("<Value Type=\"Integer\">{0}</Value>", idLookup));
                        }
                        queryCAML.Query = string.Format("<Query><Where><In><FieldRef LookupId=\"TRUE\" Name=\"{0}\" /><Values>{1}</Values></In></Where></Query>",  listaDocumentos.Fields["Temática"].InternalName,  sb.ToString());
                        SPListItemCollection items = listaDocumentos.GetItems(queryCAML);
                    }
                }
            }
}

 

Mediante el motor de búsqueda de SharePoint también podremos realizar filtros en base a términos. La propiedad de búsqueda “owstaxIdMetadataAllTagsInfo” nos permite filtrar por un identificador de un término. Además, cada vez que se agregue una nueva columna a una lista del tipo “Metadatos administrados” el motor de búsqueda crear una propiedad administrada para filtrar sobre esa columna, esta propiedad se creará con la estructura “owstax{NombreInternoDeColumna}”.

image

 

En el siguiente ejemplo se muestra cómo realizar una búsqueda con el motor de búsqueda de todos aquellos documentos catalogados con un término:

 

using Microsoft.Office.Server;
using Microsoft.Office.Server.Search;

using Microsoft.Office.Server.Search.Query;

 

public static void ObtenerElementosConBuscador() 
{
           using (SPSite site = new SPSite("
http://UrlColecciónDeSitios"))
           {
               TaxonomySession session = new TaxonomySession(site);
               TermCollection termColl = session.GetTerms("Automóvil", true);

               FullTextSqlQuery myConsulta = new FullTextSqlQuery(site);
               myConsulta.RowLimit = 10; 
               myConsulta.QueryText = string.Format("SELECT Title, Author, URL FROM Scope() WHERE (\"SCOPE\" = 'Todos los sitios') AND (\"owstaxIdMetadataAllTagsInfo\"='#0{0}')", termColl[0].Id);
               myConsulta.ResultTypes = ResultType.RelevantResults;
               ResultTableCollection misResultados = myConsulta.Execute();
               ResultTable resultadosRelevantes = misResultados[ResultType.RelevantResults];
           }
}

 

En el filtro se ha utilizado la propiedad owstaxIdMetadataAllTagsInfo indicando un valor del tipo “#0{GUID del término}”. No se puede utilizar la propiedad owstaxIdMetadataAllTagsInfo en la parte de consulta Select, solo podremos utilizarla en la parte Where.

 

 

Podréis encontrar más información en:

http://msdn.microsoft.com/en-us/library/ff625182.aspx

jueves, 1 de julio de 2010

SharePoint 2010: System.IO.FileNotFoundException

Al crear una aplicación de consola o un artefacto distinto al que nos proporciona VisualStudio 2010 con las plantillas para SharePoint 2010 nos podemos encontrar que al conectar con la Colección de Sitios nos salte una excepción del tipo System.IO.FileNotFoundException:

The Web application at{Url Colección de sitios} 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.

Si estás seguro que la url de la Colección de sitios está bien escrita y el usuario con el que se ejecuta el proceso tiene acceso, verifica que tu código se ha compilado para plataforma x64. Y es que SharePoint 2010 solo corre sobre 64 bits por lo que nuestros ensamblados tendrán que generarse para esa plataforma. Por defecto, las plantillas básicas de proyectos de Visual Studio 2010 (aplicaciones de consola, de formulario, …) tienen activa la plataforma “x86”, por lo que tendremos que cambiar a x64 y volver a compilar nuestros assemblies.

Desde Visual Studio 2010 > Menú generar > Administrador de configuración: en el desplegable “Plataforma de soluciones activas” seleccionaremos la opción “Nueva”. Se abrirá una nueva ventan en la que indicaremos que la nueva plataforma será “x64” y que copie la configuración de “x86”. Aceptaremos y generaremos de nuevo el proyecto.

image image