Posts recientes

El contenido de este blog tiene una licencia Creative Commons.
Creative Commons

Cadena de conexión Sharepoint - Reporting Services

Para poder conectar un informe de Reporting Services con SharePoint no se puede realizar de la forma habitual mediante una consulta contra SQL, se ha de trabajar atacando el webservice facilitado por SharePoint.

Recordar que los webservices trabajan estructurados en formato XML, así pues de esta manera la consulta que se tendrá que usar en el informe también tendrá que ser en este formato para que se pueda comunicar de forma correcta.


Aquí dejo un ejemplo de cómo sería la consulta definida para poder acceder a un registro concreto de una lista definida en SharePoint:


<Query>
   <SoapAction>http://schemas.microsoft.com/sharepoint/soap/GetListItems</soapaction>
    <Method Namespace="http://schemas.microsoft.com/sharepoint/soap/" Name="GetListItems">
       <Parameters>
          <Parameter Name="listName">
             <DefaultValue>[NombreDeLaLista]</DEFAULTVALUE>
          </Parameter>
          <Parameter Name="viewFields" Type="xml">
           </Parameter>
          <Parameter Name="query" Type="xml">
          </Parameter>
 </Parameters>
 </Method>
 <ElementPath IgnoreNamespaces="True">
   GetListItemsResponse/GetListItemsResult/listitems/data/row
 </ElementPath>
 </Query>

Como se puede ver el único parámetro que tiene un valor definido es el que hace referencia al nombre de la lista, esto es así por que los otros parámetros también tienen que estar definidos en el formato XML, esto se hace de la siguiente forma:

- Ir a la pestaña datos del informe.
- Acceder a las propiedades del conjunto de datos.
- Ahora seleccionar la pestaña parámetros.
- Definir los parámetros query y viewFields.
- Poner los valores correspondientes a cada parámetro.

 

Aquí dejo un ejemplo de cada uno de ellos:

query:

="<Query>
   <Where>
    <Eq>
     <FieldRef Name=""ID""/>
     <Value Type=""Integer"">" & Parameters!ID.Value & "</Value>
    </Eq>
   </Where>
  </Query>"

viewFields:

="<ViewFields>
   <FieldRef Name='ID' />
   <FieldRef Name='Campo_1' />
   <FieldRef Name='Campo_2' />
   <FieldRef Name='Campo_3' />
  </ViewFields>"

Realizando esta serie de pasos ya podréis comunicar Reporting Services con SharePoint.

Autor: David Acosta Lesmes
Publicado: 18/05/2012  10:03 | 0  Comentarios | 0  Enlaces a este post

Títulos de página en páginas de publicación de SharePoint

Implementando una web en SharePoint 2010 quería añadir el nombre de la empresa al lado del título de cada página. Para ello, modifiqué la master para que el cambio se aplicara fácilmente a toda la web de la siguiente forma:

<title runat="server"><asp:ContentPlaceHolder id="PlaceHolderPageTitle" runat="server">SiteName</asp:ContentPlaceHolder> | Nombre de la empresa</title>

Una vez implementado, veía que dicho código no funcionaba. Finalmente encontré que lo que se quería añadir tenía que ponerse dentro de otro ContentPlaceHolder, de la siguiente forma:

<title runat="server"><asp:ContentPlaceHolder id="PlaceHolderPageTitle" runat="server">SiteName</asp:ContentPlaceHolder><asp:ContentPlaceHolder id="PlaceHolderPageTitle2" runat="server"> | Nombre de la empresa</asp:ContentPlaceHolder></title>

Autor: Anna Vilalta Gili
Publicado: 11/05/2012  9:54 | 0  Comentarios | 0  Enlaces a este post

Permitir el acceso anónimo a páginas de SharePoint en el directorio _layouts

En algunas ocasiones os encontraréis con la posible necesidad de incorporar páginas de SharePoint en el mismo directorio _layouts. Algunos ejemplos: Páginas de login, mantenimientos, etc… En mi caso fueron páginas que implementaban un TPV para una web en SharePoint 2010.

En el proyecto en Visual Studio 2010, las páginas se encuentran debajo el directorio Layouts. Para hacerlo, se debe hacer clic con el botón derecho sobre el proyecto 'SharePointProject1' > 'Agregar' > 'Carpeta asignada "Layouts" de SharePoint'.

image 

Automáticamente, SharePoint añade una carpeta con el nombre del proyecto dentro de 'Layouts'. Agregamos en ella la página de aplicación.

image

Por defecto la página hereda de LayoutsPageBase. Lo único que se tiene que hacer es cambiar esa herencia por UnsecuredLayoutsPageBase.

Public partial class ApplicationPage: UnsecuredLayoutsPageBase

Luego se tiene que sobrescribir la siguiente propiedad para permitir el acceso anónimo:

Protected override bool AllowAnonymousAccess { get { return true; } }

Una vez implementada la solución, se debería poder acceder a la página (http://miUrlDeSharePoint/_layouts/SharePointProject1/ApplicationPage.aspx) sin que te pida usuario y password.

Autor: Anna Vilalta Gili
Publicado: 08/05/2012  9:51 | 0  Comentarios | 0  Enlaces a este post

Eliminar una plantilla de sitio de la galería de soluciones de SharePoint

Recientemente me he encontrado un problema al crear plantillas de sitio, o más bien al eliminarlas. Una vez se crea la plantilla de sitio con la opción Guardar como plantilla de la administración de un sitio ya existente, esa plantilla queda almacenada en la galería de soluciones de la colección de sitios. Para eliminarla se debe desactivar antes, pero es tarea imposible.

Después de muchas pruebas y intentos de encontrar formas alternativas para deshacerme de las plantillas de la galería de soluciones he encontrado la solución más efectiva. Se trata de ejecutar un comando de PowerShell.

Uninstall-SPUserSolution -Identity nombre_plantilla.wsp -Site http://misitio

 

Podéis encontrar más información sobre este comando en Technet.

Autor: Rubén Claramunt Vicente
Publicado: 26/04/2012  21:08 | 0  Comentarios | 0  Enlaces a este post

Establecer una página maestra común en SharePoint Foundation 2010

Existen diversas manera de establecer una misma página maestra para los nuevos sitios que se crean en una solución web en SharePoint Foundation 2010. Existe una forma muy sencilla de lograr tal menester, sin necesidad de definiciones de plantillas de sitio ni cambiando definiciones de sistema. Con el desarrollo de un manejador de eventos de algunas lineas de código podemos lograr mantener un aspecto uniforme sea cual sea la plantilla de sitio que se utilice para crear nuevos sitios.

El objetivo de este manejador es que cada vez que se cree un nuevo sitio se le configure de forma automática sus propiedades referentes a páginas maestras con la misma configuración que la de la web principal o raíz de la colección. Para ello debemos capturar el momento en que se crea un nuevo sitio y actuar. Para ello heredaremos nuestra clase manejadora de la clase SPWebEventReceiver de SharePoint. El código que debemos generar para nuestra clase debe ser algo parecido a:

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

namespace Trentia.SharePoint.EventReceivers
{
    public class MasterPageEventReceiver : SPWebEventReceiver
    {
        public override void WebProvisioned(SPWebEventProperties properties)
        {
            Guid siteId = properties.SiteId;
            SPSecurity.RunWithElevatedPrivileges(() => {
                using (SPSite site = new SPSite(siteId))
                {
                    using (SPWeb web = site.OpenWeb(properties.WebId))
                    {
                        web.MasterUrl = site.RootWeb.MasterUrl;
                        web.CustomMasterUrl = site.RootWeb.CustomMasterUrl;
                        web.Update();
                    }
                }
            });
            base.WebProvisioned(properties);
        }       
    }
}

Este código debe ser encapsulado en un ensamblado y generarse una nueva característica para ser instalada y activada en las colecciones de sitio en que necesiteis uniformizar las páginas maestras.

Fichero Feature.xml

<?xml version="1.0" encoding="utf-8" ?>
<Feature  Id="15E67DAC-6044-463C-B7E2-41D4D5157DE1"
          Title="Página maestra común"
          Description="Establece las configuraciones de página maestra para todas las webs creadas a partir de las configuraciones de la web principal"
          Version="1.0.0.0"
          Scope="Site"
          xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="elements.xml" />
  </ElementManifests>
  <Properties />
</Feature>

Fichero Elements.xml

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Receivers>
    <Receiver>
      <Name>MasterPageEventReceiver</Name>
      <Type>WebProvisioned</Type>
      <Assembly>Trentia.SharePoint.EventReceivers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=169a06543af62ea6</Assembly>
      <Class>Trentia.SharePoint.EventReceivers.MasterPageEventReceiver</Class>
      <SequenceNumber>10000</SequenceNumber>
      <Synchronization>Synchronous</Synchronization>
    </Receiver>
  </Receivers>
</Elements>

Autor: Anna Vilalta Gili
Publicado: 26/04/2012  16:16 | 0  Comentarios | 0  Enlaces a este post

Nueva versión de Umbraco en MVC 3

La versión 5 del conocido gestor de contenidos web Umbraco está disponible desde enero de 2012. La nueva versión, inicialmente denominada “Jupiter”, ha sido reconstruida para adaptarse a la arquitectura ASP.NET MVC 3, lo cual es una buena noticia para todos los desarrolladores que trabajan con Umbraco. Tambien es una buena noticia que a pesar de la actualización de arquitectura se consevan todas las funcionalidades de la versión anterior.

La nueva arquitectura ofrece un mayor rendimiento y mayores posibilidades de integración con sistemas externos a Umbraco.

Sitio web: http://umbraco.com

Descarga (desde CodePlex): http://umbraco.codeplex.com/

Autor: Rubén Claramunt Vicente
Publicado: 28/03/2012  15:40 | 0  Comentarios | 0  Enlaces a este post

Solucionar problema con la intercalación desde linq

En caso de necesitar realitzar búsquedas contra el motor de base de datos sin tener en consideración mayúsculas/minusculas, acentos y otros símbolos de puntuación, desde SQL Server es necesario que la base de datos use una intercalación *_CI_AI
Pero aunque la base de datos esté bien configurada para que las consultas sean no sensitivas a este tipo de carácteres, si se realiza la consulta desde nuestra aplicación la consulta no será efectiva puesto que desde linq no se explota la facilidad que nos ofrece la base de datos.
Para solucionar esto hay un método que es el que muestro en el siguiente código:
string ntext = new string("TEXTO_A_BUSCAR".Normalize(NormalizationForm.FormD).Where(c => c < 128).ToArray());
Lista = Lista.Where(x => (UTF8Encoding.UTF8.GetString(UTF8Encoding.GetEncoding("ISO-8859-8").GetBytes(x.CAMPO_BD)).IndexOf(ntext, StringComparison.InvariantCultureIgnoreCase) > -1)).ToList();

En la primera instrucción normalizamos el texto a localizar en la base de datos, y en la segunda se realiza la búsqueda en sí misma sobre el campo de la base de datos con el cual deseamos hacer el filtro.

Espero que os sirva de ayuda.

Autor: David Acosta Lesmes
Publicado: 03/02/2012  14:43 | 0  Comentarios | 0  Enlaces a este post

Error al cargar y ejecutar el receptor de eventos. “<nativehr>0x8007047e</nativehr>”

Necesitaba que al crear cualquier site todas sus páginas tuviesen un diseño de página customizado.

Aunque en la configuración del site padre tenía configurado que tan sólo podían crearse páginas con el diseño de página en concreto, cuando se creaba el site, la página por defecto (Pages/default.aspx) seguía teniendo el diseño de página “WelcomeLinks”.

Para cambiarlo creé un EventReceiver sobreescribiendo el WebProvisioned (que se dispara una vez que el site se ha creado). Dentro del método, cambiaba el PageLayout y también su ContentType también customizado (añadiéndolo también a la biblioteca de Páginas, ya que no existía por defecto).

Éste es el código del event receiver:

SPWeb w = properties.Web;
PublishingWeb curPubWeb = PublishingWeb.GetPublishingWeb(properties.Web);
SPSite s = properties.Web.Site;
SPContentType contentType = s.RootWeb.ContentTypes["PaginaInvestigador"];
SPList spList = curPubWeb.PagesList;
PublishingPageCollection ppc = curPubWeb.GetPublishingPages();

foreach (PageLayout curLayout in curPubWeb.GetAvailablePageLayouts())
{
     if (ppc.Count > 0)
     {
          PublishingPage curPage = ppc[0];
          curPage.CheckOut();
          curPage.Layout = curLayout;
          curPage.ListItem["ContentTypeId"] = curLayout.AssociatedContentType.Id;
          curPage.ListItem.Update(); 
          curPage.Update();
          curPage.CheckIn(""); 
     }        
}

Para probarlo creaba un nuevo sitio. Cuando lo había creado intentaba editar la página default para comprobar que tanto el diseño de página como el tipo de contenido se habían cambiado correctamente y me daba el siguiente error:

Error al cargar y ejecutar el receptor de eventos Client.Web.SharePointApp.ResearcherSiteEventReceiver.ResearcherSiteEventReceiver en Client.Web.SharePointApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d3b00d8781e2eddd. A continuación se incluye información adicional.

: <nativehr>0x8007047e</nativehr><nativestack></nativestack>

Lo solucioné registrando el event receiver como síncrono de la siguiente forma:

En el fichero Elements.xml, añadir dentro de <Receiver>:

<Synchronization>Synchronous</Synchronization>

Autor: Anna Vilalta Gili
Publicado: 25/01/2012  10:40 | 0  Comentarios | 0  Enlaces a este post

Solucionar problema con los diseños de página al actualizar o subir una backup de otra solución o granja

En determinadas ocasiones, cuando actualizamos nuestros desarrollos en máquinas o entornos de producción, nos damos cuenta que en algunas páginas de publicación, cuando las queremos editar, apuntan hacía un Page Layout o diseño de página que apunta hacía una URL del entorno de desarrollo.

No tiene fácil solución, ya que desde el entorno de SharePoint o desde el Designer no se pueden actualizar las referencias.

Por tanto, la única solución fácil y viable es actualizarla a través de código.

A continuación os adjunto una muestra del código que deberéis de aplicar en el caso que queráis aplicar o corregir el diseño de página de una página concreta.

string SiteUrl = "http://serverUrl";
string PageName = "MyPage.aspx";
string PageLayoutURL = "/_catalogs/masterpage/WelcomeLinks.aspx";

using (SPSite site = new SPSite(SiteUrl))
{ 
	using (SPWeb web = site.OpenWeb())  
	{
		WL(web.Title);
		
		PublishingWeb spPubWeb = PublishingWeb.GetPublishingWeb(web);    
		SPList pages = spPubWeb.PagesList;   
		
		foreach (SPListItem item in pages.Items)    
		{
			PublishingPage pubPage = PublishingPage.GetPublishingPage(item);       
			SPFieldUrlValue url = new SPFieldUrlValue(pubPage.ListItem[FieldId.PageLayout].ToString());
			
			if(pubPage.Name==PageName)
			{
				WL(pubPage.Name);
				WL(url.Url.ToString());
				
				SPFieldUrlValue newurl = new SPFieldUrlValue(PageLayoutURL);          
			
			Console.WriteLine(pubPage.Name);          
			
			pubPage.CheckOut();          
			
			pubPage.ListItem[FieldId.PageLayout] = newurl;          
			
			pubPage.ListItem.UpdateOverwriteVersion();           
			
			pubPage.ListItem.File.CheckIn("Fixed URL to page layout.", SPCheckinType.MajorCheckIn);   
			}
			
			
			
		}
	}
}
Autor: Javier Tirado Pampín
Publicado: 23/01/2012  17:18 | 0  Comentarios | 0  Enlaces a este post

Desarrollo de aplicaciones móviles multiplataforma

Las tendencias tecnológicas actuales están dejando tres claros competidores en el mercado de las plataformas móviles: iOS, Android, RIM (Blackberry) y más recientemente Windows Phone. El desarrollo de una aplicación multiplataforma implica la inversión multiplicada de esfuerzos para conseguir un instalable para cada una de estas tecnologías. Es por ello que se está produciendo una clara apuesta hacía la utilización de tecnologías homogéneas que permitan disponer de la diversas versiones de una aplicación con un único desarrollo.

En esta línea han aparecido diversos frameworks de desarrollo y herramientas. HTML5 abandera este movimiento, y se erige como punta de lanza de la base tecnológica para las aplicaciones móviles desde hoy mismo. La nueva versión de HTML permite generar aplicaciones que pueden ser entendidas por todas las plataformas y que nos aisla como desarrolladores de los detalles de cada plataforma (Java, .NET, ObjectiveC…). Desarrollamos en HTML5 una única aplicación, haciendo uso de otros frameworks, como JQuery y JQuery Mobile, que nos permite reproducir el comportamiento de una aplicación típica móbil en cuanto al aspecto visual mediante HTML y Javascript. Para la comunicación con servidor podemos hacer uso de servicios web, traspasando datos en formato SOAP o JSON. Con esta mezcla tecnológica conseguimos aplicaciones web que funcionan en cualquier plataforma, pero la usabilidad no es óptima ya que el usuario nota los tiempos de espera en las transiciones entre pantallas, además de requerir conexión permanente con el servidor web.

Para solucionar este último escollo y conseguir aplicaciones realmente nativas, han aparecido utilidades que nos permiten obtener aplicaciones nativas a partir de nuestros desarrollos en HTML5. Una de ellas, una de las más extendidas y conocidas, PhoneGap, nos permite compilar nuestra aplicación y obtener paquetes instalables nativos para cada plataforma.

image

Deberemos ver hacía dónde evoluciona todo ello, pero parece claro que para una gran cantidad de aplicaciones comerciales móviles han pasado los tiempos en que se debía desarrollar para plataformas específicas.

Autor: Rubén Claramunt Vicente
Publicado: 16/01/2012  22:59 | 0  Comentarios | 0  Enlaces a este post

 Siguiente >>