Microsoft.SharePoint.Utilities: el namespace que vale su peso en oro (1)
15.12.10 / Comments (0) / by Unknown
Quien más quien menos conoce el cajón de sastre llamado SPUtility y sus métodos miscelánicos. Ahora os propondré un viaje en distintos capítulos por algunas otras clases de indiscutible utilidad. Hoy para empezar:
SPHttpUtility o cómo olvidarse para siempre de string.Replace
La intención de esta clase estática es proveer de métodos también estáticos para la codificación y decodificación de strings durante el procesamiento de peticiones web. Lo más interesante es:
string ConvertSimpleHtmlToText(string html, int maxLength)
Convierte una cadena html (por ejemplo, de un campo de rich text o un PublishingContent) a texto plano, eliminado los tags HTML. ¿A que te estás dando de cabezazos?
string HtmlEncode(string valueToEncode)
Codifica una cadena de texto para ser incluída en markup HTML, es decir, reemplaza " / ' / < / > / & por " / ' / < / > / & . Opcionalmente tenemos también el HttpUtility.HtmlEncode . A ver, que el Regex que implementaste está muy bien pero...
string HtmlDecode(string valueToDecode, bool decodeNbsp)
El correspondiente método de decodificación. "decodeNbsp" a true para si deseamos decodificar también los a espacios.
string HtmlEncodeAllowSimpleTextFormatting(string valueToEncode)
Codifica una cadena para aparecer entre merkup HTML pero además sustituye los espacios y saltos de línea por y <br/> (eso sí, codificados a &nbsp; y <br>).
string UrlKeyValueEncode(string keyOrValueToEncode)
Codifica una clave o valor de una querystring para construir una URL, es decir, escapa los caracteres no admitidos por un querystring. El HttpUtility.UrlEncode de toda la vida.
string UrlKeyValueDecode(string keyOrValueToDecode)
Decodifica una clave o valor de querystring.
string EcmaScriptStringLiteralEncode(string scriptLiteralToEncode)
Veamos, ésta no es de utilidad inmediata pero en algunas funcionalidades de SP, hay que transferir strings a traves de JavaScript (ECMAScript), para lo cual algunos caracteres necesitan ser codificados a formato Unicode (\u00XX). Este método proporciona dicha codificación.
POSTEADO EN: Modelo de objetos, SharePoint 2007, SharePoint 2010, Utilidades Enviar por correo electrónico Escribe un blog Compartir en X Compartir con Facebook
Enviar entrada a: Digg + Del.icio.us + Google Bookmarks + Reddit + Technorati
SharePoint 2007: Reemplazar master page en páginas de aplicación
10.12.10 / Comments (0) / by Unknown
La application.master que viene de serie en las páginas del directorio _layouts es una cruz que nos tortura constantemente a los desarrolladores de SharePoint. Es única por servidor, no está soportado el modificarla y, para colmo, las páginas de aplicación que la usan son múltiples y habituales (newsbweb.aspx, createpage.aspx, mysubs.aspx,...). Con lo cual, es frecuente el requerimiento de que estas páginas dispongan de un look&feel como mínimo parecido al del resto de páginas del sitio (ya sean páginas de publicación o páginas de formulario -DispForm.aspx, EditForm.aspx,...-, a las que no hay problema para asignarles una master page). Y con toda la razón del mundo, porque el aspecto de esas páginas canta como una almeja.
A riesgo de meter la pata en el hoyo de lo "not supported", voy a proponer un mecanismo, a mi juicio bastante limpio, para reemplazar la master page en tiempo de ejecución para esas páginas. Está comprobado con muchas de las páginas de aplicación, aunque no garantiza su efectividad en el 100% de ellas. Y no, no hay ningún HttpModule de por medio.
Si implementamos un page adapter para estas páginas de layout, podemos tener control de sus propiedades en runtime. Ahora sólo quedaría modificar la propiedad MasterPage, el pequeño inconveniente es que sólo puede modificarse antes o durante del método OnPreInit() y que ese método no existe en un control adapter. Bueno, un vistazo al ciclo de vida de los controles ASP.NET, y veremos que existe un evento DeterminePostBackMode() invocado justo antes de OnPreInit. Este evento procesa los datos enviados por postback a la petición actual, estableciendo el valor IsPostBack y devolviendo la colección de valores recibidos. Sí, sí, muy bien. Pero de lo mío, ¿qué? Bien, pues si el page adapter sobreescribe este evento, llama al base (importante no olvidarlo) y luego modifica la propiedad MasterPageFile, bingo! Tenemos una página de aplicación con la master page deseada.
/// <summary>
/// Adapter for SharePoint layout pages to replace their masterpage
/// </summary>
public class CustomLayoutPageAdapter : PageAdapter
{
public override System.Collections.Specialized.NameValueCollection
DeterminePostBackMode()
{
NameValueCollection result = base.DeterminePostBackMode();
try
{
Page page = this.Control as Page;
page.MasterPageFile = "/_catalogs/masterpage/XXXXXX.master";
}
catch { }
return result;
}
}
Ahora sólo queda utilizar este page adapter, creando un fichero my.compat.browser en App_Browsers con una definición <adapter> para cada página de aplicación que queramos reemplazar. ¿Engorroso? Depende, esto nos asegura que estaremos reemplazando la master page sólo en las páginas que queremos y no a lo loco, en todo el back-office de SharePoint. Ejemplo:
<adapter controlType="Microsoft.SharePoint.Publishing.Internal.CodeBehind.CreatePagePage,
Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" adapterType="MyNamespace.CustomLayoutPageAdapter,
MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXX" />
¿Cómo obtengo el tipo correspondiente a una página de aplicación? Normalmente se ve fácil consultando el código fuente de la página y identificando su clase codebehind. Aquí van una cuantas páginas típicas y sus tipos:
createpage.aspx
Microsoft.SharePoint.Publishing.Internal.CodeBehind.CreatePagePage, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
mysubs.aspx
Microsoft.SharePoint.ApplicationPages.MySubsPage, Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
sitesubs.aspx
Microsoft.SharePoint.ApplicationPages.SiteSubsPage, Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
newsbweb.aspx
Microsoft.SharePoint.ApplicationPages.SubNewPage, Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
checkin.aspx
Microsoft.SharePoint.ApplicationPages.CheckIn, Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
userdisp.aspx
Microsoft.SharePoint.ApplicationPages.UserDisplayPage, Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
regionalsetng.aspx
Microsoft.SharePoint.ApplicationPages.RegionalSettingsPage, Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
subchoos.aspx
Microsoft.SharePoint.ApplicationPages.SubChoosPage, Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
Pero esto no es todo. Es muy importante notar que, si reemplazamos una application.master por una master page nuestra, es probable que las páginas de aplicación a las que hemos lobotomizado empiecen a echar en falta placeholders y controles, con la consecuente eclosión de fuegos artificiales diversos. Solución: localizar cuáles son esos placeholders y añadirlos a nuestra masterpage. Esto no es ciencia exacta: debemos testear cada página a la cual estamos aplicando este fix y asegurarnos que funciona correctamente. Dejadme solo apuntar que para la mayoría de páginas de aplicación, el PlaceHolderFormDigest es necesario.
<asp:ContentPlaceHolder id="PlaceHolderFormDigest" runat="server">
<SharePoint:FormDigest ID="FormDigest1" runat=server/>
</asp:ContentPlaceHolder>
Y nada más, si alguien aplica este método y quiere dar feedback sobre él, soy todo oídos.
POSTEADO EN: Application Pages, Fixes, Masterpages, SharePoint 2007 Enviar por correo electrónico Escribe un blog Compartir en X Compartir con Facebook
Enviar entrada a: Digg + Del.icio.us + Google Bookmarks + Reddit + Technorati