viernes, 18 de mayo de 2012
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.
viernes, 11 de mayo de 2012
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>
martes, 08 de mayo de 2012
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'.
Automáticamente, SharePoint añade una carpeta con el nombre del proyecto dentro de 'Layouts'. Agregamos en ella la página de aplicación.
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.
jueves, 26 de abril de 2012
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.
jueves, 26 de abril de 2012
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>
miércoles, 28 de marzo de 2012
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/
viernes, 03 de febrero de 2012
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.
miércoles, 25 de enero de 2012
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>
lunes, 23 de enero de 2012
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);
}
}
}
}
lunes, 16 de enero de 2012
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.

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.
Siguiente >>