Social Icons

jueves, 25 de abril de 2013

Necesitamos desarrolladores

StratexSystems está creciendo y hemos pensado en crear una sucursal en España. Nuestro primer objetivo es contratar a dos o tres desarrolladores de SharePoint que sean capaces de depurar, mejorar y ampliar StratexPoint, que es una solución de RBPM completamente creada en SharePoint.

Tenemos clientes muy interesantes en el mundo financiero que necesitan software de la mejor calidad y necesitamos a gente que sea buena en SharePoint y que además tenga interés por aprender y utilizar nuevas tecnologías. Actualmente ya tenemos una aplicación para Windows 8 que estamos deseando de mejorar, un par de servicios en Azure y planes para construir un portal en HTML5 además de estar estudiando un cambio de plataforma a SharePoint 2013.

No importa en qué parte de España estés siempre y cuando tengas un buen nivel de inglés. Vamos a tener la mitad del equipo en España y la otra mitad en Londres por lo que las reuniones serán mayoritariamente en inglés.

Si eres un desarrollador de SharePoint con experiencia y buscas nuevos retos mándanos tu cv.

Puedes ver la oferta de trabajo aquí.
Publicar un comentario

martes, 23 de abril de 2013

Desayuno para Ejecutivos de StratexSystems en Londres

En la primera reunión para ejecutivos del 2013, StratexSystems invitó a dos de sus clientes a compartir sus experiencias en las diferentes etapas del viaje que representa la gestión del riesgo institucional (Enterprise Risk Management).

+Andrew Smart hizo una pequeña demostración a los asistentes de StratexPoint y la metodología de gestión de riesgo institucional basada en el rendimiento (Risk Based Performance Management) además de presentar a Gillian y a Kevin que también participaron.

Para los que os preguntéis en qué trabajo, aquí tenéis una muestra:

 

La primera presentación, por parte de los invitados, fue un caso de estudio de uno de los bancos más nuevos y de más rápido crecimiento en el Reino Unido  (Aldermore Plc).

De la mano de su Jefe de Riesgo Operacional, Kevin Pearce, este caso de estudio cuenta la historia de una organización que se encuentra en una fase relativamente temprana del camino del ERM.

Kevin nos contará algunos trucos sobre cómo establecer una agenda de ERM y como hacerla relevante en una organización de rápido crecimiento enfocada a dar mucho valor tanto a los clientes como a los accionistas.

 

La segunda presentación es un caso de estudio de la empresa contratista de sercicios financieros más grande del Reino Unido (HML) y fue conducida por la Directora de Gestión de Riesgo Empresarial, Gillian Weatherill.

En esta charla, Gillian comparte con nosotros su experiencia de más de cinco años en el camino del ERM y cómo consiguieron reducir un 60% sus pérdidas operativas y un 23% sus provisiones de capital en 18 meses.

 

Puedes encontrar más información sobre Reuniones de Ejecutivos, Webinars y soluciones de software en http://www.stratexsystems.com

¡Muchas gracias Gillian y Kevin!

Buen video James.
Publicar un comentario

lunes, 22 de abril de 2013

Editando SPListItems desde SPWeb.GetSiteData

En mi solución tengo un número desconocido de subsitios que contienen un número desconocido de SPListItems que necesitan ser actualizados. Parece la manera perfecta de probar el  GetSiteData.

La documentación es útil y podrás probar las consultas sin problemas ¿De verdad? Síp la documentación está bien pero este método trae de vuelta un objeto DataTable y yo lo que necesito es actualizar los SPListItems.

Bueno, si miras al DataTable verás que tienes todo lo necesario para traerte el SPListItem fácilmente.

Me he creado un extension method, bueno dos,... Me encantan los extension methods.
public static SPListItem GetListItemFromSiteData(this DataRow ItemRow, SPSite ParentSite)
{
    using (SPWeb Web = ItemRow.GetWebSiteData(ParentSite))
    {
        return Web.Lists[new Guid(ItemRow["ListId"].ToString())].GetItemById(Convert.ToInt32(ItemRow["ID"]));
    }
}

public static SPWeb GetWebSiteData(this DataRow ItemRow, SPSite ParentSite)
{
    return ParentSite.OpenWeb(new Guid(ItemRow["WebId"].ToString()));
}

Usando estos dos podrás iterar fácilmente por la colección de filas del DataTable, seleccionar qué elementos necesitan ser actualizados y actualizarlos.

No he probado cómo de rápido es comparado con traerte los objetos con una CAML query. No tener que crear la SPListItemCollection podría hacer este método más rápido y más conveniente para según que cosas... Lo probaré,
Publicar un comentario

domingo, 21 de abril de 2013

Batería y Tiles de Acceso Directo para WP8


Como posiblemente sabrás conseguí mi WP8 hace un par de semanas. Una de las cosas que me molesta es tener que ir a Configuración>LoQueSea>LoQueQuieres y lo suelo hacer un par de veces al día, todos los días. Eso quiere decir que me molesta 730 veces al año...

Genial! pensé. Voy a hacer una aplicación con tiles de accesos directos y por fin voy a tener una app en el marketplace que sea útil, una que tenga sentido.

Mientras me descargaba la SDK pensé que podría estar bien tener una aplicación que me dijese el nivel de la batería en una tile "Alguien debe haber hecho esto ya, iré al marketplace y pillaré alguna" Y tenía razón.

En el marketplace encontré Battery, una estupenda aplicación que muestra una gráfica con el nivel de la batería, tiene estadísticas sobre todo lo imaginable, te dice el nivel de carga y hasta te da una estimación del número de horas restantes hasta la próxima carga. ¡Excelente app! ¡este tío ha pensado en todo! pero... ¿Qué es eso? Oh, otra vez no... Sí, tiles de acceso directo.

La aplicación proporciona un juego de tiles de acceso directo y funcionan perfectamente. WiFi, Localización, Bluetooth, Modo vuelo y Red Movil. Y mi plan era crear accesos directos para el WiFi y el Modo Vuelo solamente...

Obviamente no voy a hacer la app para los accesos directos, ya hay un montón en el marketplace. Pero si lees este post y tienes un WP8 prueba esta app. Te ayuda a trabajar más rápido con el teléfono y, en mi opinión, las tiles lo hacen parecer más geek. Ahora me gusta usar estas tiles de accesos directos y eso me hace feliz 730 veces al año.


¿Se me ocurrirá alguna vez una idea para una app?.
Publicar un comentario

¿Cursos de Universidad Gratis? Coursera


Edicación gratis. Mejor imposible.

Escuché hablar sobre estos cursos hace cosa de un mes y me ha apuntado a dos. El primero empieza el lunes que viene así que no puedo decir si son buenos o si valen la pena todavía pero tienen muy buena pinta.

Me he apuntado a un curso de inteligencia artificial y otro de programación.

La inteligencia artificial es un campo que me llama mucho la atención y en el que no tengo ninguna clase de experiencia. ¿No sería bonito poder ponerle un poco de inteligencia a cualquier cosa en la que estés trabajando? Creo que podría dar valor añadido a a alguna cosa, y si no pues por lo menos he satisfecho mi curiosidad.

Y el curso de programación también es interesante, si las cosas han cambiado en los últimos 10 años quiero saberlo y si no, quiero recordar como eran :)

Antes de apuntarme a más cursos voy a intentar acabar con estos dos, pero ya tengo el ojo echado a otro curso de arquitecturas orientadas a patrones para software concurrente...

¿Por qué no te apuntas conmigo en https://www.coursera.org?
Publicar un comentario

viernes, 19 de abril de 2013

Necesitamos un Día del Orgullo Programador

Cada vez que estoy buscando un desarrollador senior es lo mismo.

Parece que si has sido programador cuatro años ya no puedes seguir programando. Ahora tienes que ser jefe de equipo o jefe de desarrolladores o un consultor preventa y cualquier cosa menos que eso es una vergüenza para tu carrera. ¿Por qué un programador es menos que un jefe de equipo? ¿Me lo puede explicar alguien?

¿Cómo puede alguien después de cuatro años decir que tiene tanta experiencia que ya no quiere programar más?

Recuerdo una vez que estaba contratando un desarrollador en Madrid y un chaval buscando su primer empleo después de terminar la universidad me dijo que él no iba a programar porque él era ingeniero. Me quedé perplejo... Yo fui a la universidad precisamente para aprender a programar bien...

Para mí es como si a un futbolista no quisiera aprender a jugar al futbol porque lo que él quiere es ser entrenador.

¿Cómo piensas que vas a ser capaz de decirle a la gente qué hacer y cómo hacerlo si tú mismo no sabes porque nunca te has preocupado por aprender?

Los managers hacen falta pero me parece que la gente piensa que un desarrollador es un subproducto de un manager.

Déjame decirte algo, un desarrollador no es un tío que no valía para nada más y se tuvo que conformar con ser ignorado en una esquina de una oficina en medio de ninguna parte. Ser un desarrollador es más difícil de lo que la mayoría de la gente se piensa.

En mi caso he sido programador durante siete años, esto solo profesionalmente. He estado programando desde que tenía 9 años y me compraron mi MSX HB-20P y después de todo este tiempo me siento como si solo hubiese arañado la superficie de lo que es el desarrollo.

He visto trabajar a buenos desarrolladores y realmente marcan la diferencia. La cantidad de conocimientos que tienen es sobrecogedora igual que la claridad de sus pensamientos y la elegancia del código que hacen.

Son artistas y una clase muy impresionante de artistas. Ellos entregan diariamente, controlan la presión y superan un número infinito de problemas aprendiendo de ellos y mejorando su código y su entorno para asegurarse de que no van a tener esos problemas nunca más (ni ellos ni ninguno de los del equipo)

Los Grandes desarrolladores son generosos con su conocimiento, pregúntales sobre lo que hacen y seguramente te sentirás abrumado por la cantidad de detalles y trucos que te darán. Ellos no esconden lo que saben, les encanta compartir. Hay tanto que aprender y tan poco tiempo.

No se coge esa clase de experiencia en un par de años, cuesta toda una vida de esfuerzo convertirse en un verdadero experto en este campo. Y si no cambiamos nuestro modo de ver lo que es un desarrollador la cantidad de buenos desarrolladores que tendremos en el futuro será ridícula.

Si eres un programador siéntete orgulloso de lo que haces. Un ingeniero con infinitas piezas para elegir. Un general con infinitos soldados haciendo exactamente lo que tú les dices. Eres el hacedor.

Los desarrolladores necesitamos mejorar la manera en la que nos vemos a nosotros mismos, necesitamos cambiar la manera en que las empresas nos ven.

Necesitamos un Día del Orgullo Programador.

Si te encanta aprender nuevos trucos, si te encanta cuando una clase hace exactamente lo que quieres y la belleza de la forma en que la hiciste. Si te encanta mejorar el código en cada iteración o si eres capaz de cambiar un método, mejorarlo en un orden de magnitud, y sentirte el tío más feliz. Si te encanta programar... No cambies.

Necesitamos que seas un desarrollador. El mundo necesita que te conviertas en un Gran desarrollador. El mundo necesita que tú lo mejores.

Y eso lleva tiempo.
Publicar un comentario

jueves, 18 de abril de 2013

Patrón Recoge Tu Cuarto Después de Jugar

¿Es esto un patrón?

En la mayoría de los casos quieres cambiar el valor de una variable y dejarla así pero en algunas ocasiones quieres cambiar el valor de la variable, hacer algo y ponerla como estaba.

Con este código es muy fácil y te aseguras de que no te vas a olvidar nunca.

La idea es crear una clase que implemente la interfaz IDisposable y guarde los valores en el estado en el que estaban cuando se creó y luego los ponga a lo que necesitemos. Después, en el Dispose, los cambiará otra vez a los valores iniciales:
public class ManageAllowUnsafeUpdates : IDisposable
{
    private readonly bool allowUnsafeUpdatesStatus;
    private readonly SPWeb Web;

    public ManageAllowUnsafeUpdates(SPWeb Web)
    {
        this.Web = Web;
        allowUnsafeUpdatesStatus = Web.AllowUnsafeUpdates;
        Web.AllowUnsafeUpdates = true;
    }

    public void Dispose()
    {
        Web.AllowUnsafeUpdates = allowUnsafeUpdatesStatus;
    }
}

Usarlo es así de simple:
using (new ManageAllowUnsafeUpdates(Web))
{
    ListItem[this.FieldName] = (String)value;
    ListItem.Update();
}

Y no te tienes que preocupar nunca más de si el valor estaba a true o false antes porque la clase se ocupará de todo por ti.

Este código es un poco tonto, pero creo que sirve bien para demostrar la idea.
Publicar un comentario

miércoles, 17 de abril de 2013

Capturando Excepciones Incapturables

Mi aplicación ha estado funcionando perfectamente hasta hoy. Ahora, cada vez que la lanzo revienta sin más información que el temido CLR20r3.


Description:

  Stopped working



Problem signature:

  Problem Event Name: CLR20r3

  Problem Signature 01: appName.exe

  Problem Signature 02: 1.0.0.0

  Problem Signature 03: 516eb9fb

  Problem Signature 04: mscorlib

  Problem Signature 05: 2.0.0.0

  Problem Signature 06: 4a27471d

  Problem Signature 07: 20c8

  Problem Signature 08: 100

  Problem Signature 09: N3CTRYE2KN3C34SGL4ZQYRBFTE4M13NB

  OS Version: 6.1.7600.2.0.0.274.10

  Locale ID: 2057


He leído en internet que no me pasa esto a mi solo.

Y lo más molesto es que cuando lo estoy debugando no falla...

Al final encontré un post con respuestas Handling “Unhandled Exceptions” in .NET 2.0.

Y saqué este código, que puse en el Main de la aplicación:
AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
 {
  EventLog.WriteEntry("appName", string.Format("{0} – IsTerminating = {1}", e.ExceptionObject.ToString(), e.IsTerminating), EventLogEntryType.Error, 001);
 };
Entonces ejecuté la aplicación y reventó también, pero esta vez me dejó una hermosa excepción en el event viewer.

Si quieres saber lo que pasaba es que no era capaz de cargar una DLL que estaba esperando.

Gracias Mark.
Publicar un comentario

Los precios de las Máquinas Virtuales de Windows Azure IaaS son competitivos pero no baratos

Como probablemente sabes Microsoft acaba de lanzar la nueva plataforma de IaaS en Azure. Puedes ver todos los detalles aquí.

Todo está muy bien, pero no me gustan los precios...

Los pantallazos tienen una pinta genial (no he tenido tiempo de probarlo últimamente) y han incluido más plantillas, incluida una de prueba de SharePoint 2013 qué caducará en octubre de este año.

Pongo lo de prueba en negrita porque ¿Quién va a pagar $270 al mes para probar una máquina que se autodestruirá dentro de seis meses?

La grandeza del IaaS es que cualquiera puede crear cualquier cosa sin tener que soltar un montón de pasta en hardware, así lo veo yo. Pero, por otro lado, si el coste de la plataforma es tan cercano al del hosting tradicional, ¿dónde está la gracia?

Una búsqueda rápida te muestra cómo puedes conseguir una máquina con 4 Corea 2GB (RAM) y 500GB (HDD) por £79 al mes, ¿por qué pagar £85 por una máquina parecida albergada en la nube?

La ventaja principal de Azure es que puedes crear MVs en minutos mientras que en un distribuidor tradicional tienes que llamar por teléfono y, normalmente decirles con un mes de antelación que quieres cancelar el servicio.

Si quieres crear una granja para probar cómo conectar todo puedes hacerlo, configurarlo, jugar un poco y despues borrarlo todo por un dolar la hora, eso está bien, pero si quieres algo más estable las diferencias entre Azure y un hosting tradicional no son tan grandes.

No hace falta decir que la tecnología es asombrosa, con balanceo de carga, redes virtuales, nuevas plantillas y las máquinas nuevas de 56GB de RAM.

Y tampoco hace falta decir que tengo unas ganas enormes de ponerle las manos encima.

Pero todavía lo veo caro.
Publicar un comentario

miércoles, 10 de abril de 2013

Las Tareas han Muerto, Larga Vida a las Historias

La peor pesadilla de un scrum master o de cualquier project manager de agile es encontrarte al final del esprint con que el 80% de las tareas están hechas pero que ninguna de las historias están terminadas.

La teoría dice que las historias deben de romperse en historias más cortas si no caben en el esprint pero a mi me gustaría llevar esto up paso más allá… Cuando sea posible las tareas dentro de cada historia deben ser promocionadas a historias.

Por supuesto que esto no es siempre posible ¿o no? Depende de cómo planees las tareas de tu historia, por supuesto si creas una tarea para cada nueva función que planeas añadir entonces no puedes hacerlas historia pero, por otro lado, ¿no crees que pasas demasiado tiempo enfrente de la scrum board post-its?

Quizás si tienes un equipo de desarrollo enorme que tardas una semana en coordinarse es imposible pero, por otro lado, si tardas una semana en coordinar tu equipo ¿no crees que estás haciendo algo mal?

No sé si es posible en todos los casos, pero creo que merece la pena intentarlo. Mientras más pequeña sea la historia más control tendrás sobre el proyecto y más feedback tendrás.

¿No estaría bien mostrar las historias del día anterior en la stand up meeting? en un par de minutos, solo. Sería mucho mejor que el consabido "Si, estoy todavía trabajando en eso… Voy bien… si, sin impedimentos.”

Yo lo voy a intentar, vamos a ver cómo va. Si se lo carga todo volveré para contarlo y entenderé al fin por qué no me llamaron para ser uno de los 17 que crearon el Manifesto for Agile Software Development.
Publicar un comentario

martes, 9 de abril de 2013

Testeando en Tean Foundation Service

El Update 2 del TFS ha sido entregado el día 4 de abril con algunas nuevas funcionalidades de ALM. Me gustó la parte de testing y en este post voy a mostrar el proceso a seguir para crear un plan de test, hacer un poco de testing y añadir un bug al proyecto.

Microsoft está haciendo un gran esfuerzo para ponerse al día con el testing y aunque todavía es bastante complicado para los desarrolladores de SharePoint debemos hacerlo también porque los beneficios, en general, y la tranquilidad que da, en particular, lo merecen.

Antes de empezar necesitaremos bajar el Visual Studio Test Professional y una vez que lo tengamos estamos listos. Instalar este software solo para poder crear luego los tests en la web es matar moscas a cañonazos, pero es lo que hay…

Tu ordenador va a necesitar reiniciarse, tenlo en cuenta también.

Creando un Test Plan:
Antes de empezar necesitamos un plan…

La manera de crear un plan está perfectamente explicada aquí, no hace falta que repita los pasos aquí, básicamente necesitas abrir el Microsoft Test Manager, conectar a tu TFS y crear un plan.

¡Listo para empezar!

Creando un Nuevo Test:
Fácil.

Vas a la web de TFS y pulsas en la pestaña TEST. Haz click en New.
Tendrás que darle un nombre y asignarlo, hasta ahora sin problemas.

image

Ahora voy a añadir algunos pasos.

image

Añadir los pasos es también muy fácil y rápido. El último que he añadido es solo para asegurarme de que algo falla.

Finalmente hacemos click en Save y Close.

Ejecutar los Tests:
¡De momento ha sido fácil! ahora la parte complicada.

Para ejecutar los tests tenemos que hacer click en el botón Run, asegúrate de que permites al sitio abrir ventanas pop up porque si no no va a funcionar.

image

Si el test no aplica o está en espera podemos marcarlo así en el desplegable de la esquina superior derecha:

image

Si el test necesita ser probado tenemos que seguir manualmente cada paso y asegurarnos de que funciona. Después de testear algo haremos click en el botón verde si funciona y en el rojo si no.

En el caso de que alguno no funcione se nos pedirá un comentario sobre el error.

image

Entonces podemos crear un bug o salvar el resultado del test.

Si hacemos click en el botón para crear un bug automáticamente nos mostrará un formulario de bug con el estado de los pasos del test para facilitarnos la descripción del problema. Tendremos que darle un nombre al bug, asignarlo y darle un valor de severidad.

image

Después guardamos el casi de test y será mostrado como Fallido en el plan de tests.

image

Supondremos que el fallo ha sido arreglado y volveremos a correr el test.
Bien, todos los pasos funcionaron esta vez y el test está marcado como Pasado en el plan de test.

image

Conclusión:
Rápido, bonito y fácil.

No sé hasta qué punto esto será capaz de sustituir la infraestructura que tenemos ahora… pero sin duda tiene mejor pinta.
Publicar un comentario

lunes, 8 de abril de 2013

Localización de Nombres de Listas en SharePoint

No se puede llamar a una lista por su nombre interno por defecto en SharePoint o por lo menos, yo no se cómo, tienes que usar el nombre externo o el GUID y eso es un problema cuando hay que localizar.

Para solucionar este problema he creado un par de extensiones basadas en la URL. La idea es simple, uso una serie de variables para almacenar el "nombre interno" de las listas y siempre las llamo usando estas constantes. Hasta ahora ha funcionado bien.
/// <summary>
/// Returns null if the list is not found
/// </summary>
public static SPList GetListByInternalName(this SPListCollection Lists, string InternalName)
{
    if (string.IsNullOrEmpty(InternalName)) return null;

    Guid ListGuid = Lists.GetListIdByInternalName(InternalName);

    if (ListGuid != Guid.Empty)
        return Lists[ListGuid];

    return null;
}

/// <summary>
/// Returns the UIDC of the list
/// </summary>
static Guid GetListIdByInternalName(this SPListCollection Lists, string InternalName)
{
    if (string.IsNullOrEmpty(InternalName)) return Guid.Empty;

    foreach (SPList list in Lists)
        if (list.GetInternalName().ToLower() == InternalName.ToLower())
            return list.ID;

    return Guid.Empty;
}

/// <summary>
/// Gets the Url of the list. That's what we consider its internal name
/// </summary>
public static string GetInternalName(this SPList list)
{
    string Url = list.RootFolder.ServerRelativeUrl;

    string[] split = Url.Split('/');

    return split[split.Length - 1];
}

Después de esto el nombre externo de la lista no es relevante y la localización es simple o, por lo menos, un poco más simple.
Publicar un comentario

domingo, 7 de abril de 2013

Disfrutando de mi Lumia 920

Me habían dicho que WP8 era casi lo mismo que WP7, el mismo look / feel, las mismas tiles, la misma funcionalidad... aburrido. Me dieron el mío el miércoles y PARA NADA.

Las notificaciones funcionan como deben, cada vez que algo pasa me llega una notificación. Con WP7 esto era así solo con el correo.

Las mini tiles son una manera fantástica de mantenerse informado sobre lo que pasa en vuestras cuentas de correo y apps sin tener que hacer scroll gMail, Outlook, 2 cuentas agruparas para los correos de los productos de la compañía, my correo de la empresa, las llamadas de teléfono, SMS, Whatsapp, Yo y el calendario todo ahí. En el mismo sitio, cuando miro mi pantalla los veo todos de un vistazo.

La pantalla de bloqueo dinámica es también fantástica, me he instalado la aplicación gratuita de Accuweather y actualiza la pantalla de bloqueo con información. Qué peso me he quitado de encima ahora que no tengo que mirar por la ventana para saber si hace sol o no…

Office, OneNote, Fotos, todo esta ahora conectado a SkyDrive de manera natural y funciona como debe.

La integración con Skype es realmente buena. Por primera vez he podido hacer y recibir llamadas normalmente con el móvil y la calidad del sonido es tan buena como en las llamadas normales (tanto en 3G como, por supuesto, en WiFi)

Y por último las apps de Nokia. Con City lens he podido sentir por primera vez lo que es la realidad aumentada, lo había visto pero nunca había tenido la oportunidad de usarlo. Todas las apps Here están muy bien terminadas, la que más he usado es HERE Transit. Y por supuesto Nokia Music, no sé todavía como funciona pero he podido escuchar bastante música que yo he elegido completamente gratis.

Puede ser que estemos todavía en esa fase de la relación pero esperaba un movil aburrido igual que el anterior y me encontré con un aparato interesante que mejora y mucho la productividad y tiene una pantalla grande para los juegos.
Publicar un comentario

Los 5 errores más tontos (y comunes) de los desarrolladores de SharePoint

Si eres un desarrollador veterano probablemente estarás de acuerdo, si no tienes tanta experiencia probablemente has sufrido por lo menos uno de estos la semana pasada y perdiste una hora intentando enterarte de lo que estaba pasando.

Actualizando la web que no es
Estás cambiando algo, el código funciona, no se lanzan excepciones y vas al sitio de SharePoint para ver tu nueva obra pero no ha cambiado nada... Comprueba que estás cambiando la web que querías modificar y no otra.

Nombre de campo incorrecto
Tu CAML query esta bien, pero recibes una excepción diciendo que los campos de la lista están mal. no es la lista, eres tu Vete a los settings de la lista, a la definición del campo y alli, en la URL tienes el nombre interno del campo tal y como SharePoint espera recibirlo, si es verdad, lo tenías mal en la CAML. A mi me gusta tenerlos definidos como constantes en algún lugar, escríbelos bien una vez y deja que el intellisense te recuerde el nombre por el resto de la vida del proyecto.

Lista equivocada
El fichero que estas creando no aparece en la lista o se queja de los campos y ya lo has comprobado y están bien... Comprueba que estás conectad a la lista correcta. (Por cierto, también tengo constantes para los nombres de las listas)

DLL Incorrecta
Cambias algo en tu código pero el error sigue ahí. Dependiendo de lo que estes haciendo necesitas desplegar la DLL al gac o a la carpeta BIN, la DLL correcta, y luego resetear el servicio correcto, algunas veces no es el IIS. Intenta cambiar una string o algo muy obvio y fácil de notar para asegurarte de que estás ejecutando el código que quieres ejecutar.

Mis web services no se conectan al servidor
Necesitas crear un fichero clientaccesspolicy.xml o un crossdomain.xml y ponerlo en la carpeta de la aplicación web en el inetpub tan simple y tan molesto.
[BONUS] Los cambios que hago no aparecen en SharePoint
La lista está bien, la web está bien, los campos están bien, todo está bien y no pasa nada después de que haya cambiado el objeto... Se te ha olvidado hacer el update. Y esto es válido para un montón de objetos diferentes en SharePoint. En caso de duda yo siempre intento hacer un .Update después de modificar. Cuidado, los updates son normalmente lentos y deben ser llamados la menor cantidad de veces posible..
Publicar un comentario

viernes, 5 de abril de 2013

Encriptación de Datos Transparente para SharePoint

SharePoint implementa seguridad a nivel de usuario, si quieres acceder a un fichero pero no tienes los permisos necesarios serás bloqueado y eso es suficiente para la gran mayoría de las empresas, pero...

- ¿Qué pasa si alguien consigue acceder a tu servidor de bases de datos?
+ Podrá fácilmente descargarse la base de datos de contenido, conectarla a uno de sus servidores de SharePoint y tener acceso a todo hasta el branding.
- ¿Qué puedo yo hacer ante esto como desarrollador de SharePoint?
+ Nada.
- ¡Ay, Dios mio! ¡Ay, Dios mio!
+ Tranquilízate muchacho, si quieres encriptar las bases de datos pídeselo al tío de las bases de datos.

Sí, los administradores de base de datos pueden encriptar instancias de SQL usando TDE. Y, aunque parece fácil, estoy contento de no tener que hacerlo yo.

- ¡Pero encriptar todo va a afectar al rendimiento de mi granja!
+ Microsoft cree que solo será entre un 3 y un 5% más lenta.

Puedes conseguir más información sobre este tema aquí y aquí (por ejemplo).
Publicar un comentario

jueves, 4 de abril de 2013

Generador Dinámico de Objetos para Bloqueos

Algunas veces necesitar crear un objeto de bloqueo dinámicamente, como en el post que escribí ayer.

Cuando estás trayendo una propiedad del property bag no quieres bloquear todas las property bags de todas las webs, solo necesitas asegurarte de que la propiedad que con la que estás trabajando no ha cambiado desde que empezaste el bloqueo... y para eso hace falta una manera dinámica de crear bloqueos.

Empecé esta clase con un diccionario pero después de usarla un tiempo me di cuenta de que los diccionarios no son thread safe para lectura... así que lo cambié por una hash table.
public class Locks
{
    /// <summary>
    /// This hashtable will provide a lock for every different key in the cache. Hashtables are threadsafe for one writer many readers scenario
    /// </summary>
    private static Hashtable LocksCollection = new Hashtable();

    public static object GetLock(string Key, params object[] args)
    {
        if (args!=null)
            Key = string.Format(Key, args);
           
        if (!LocksCollection.ContainsKey(Key))
        {
            lock (LocksCollection)
                if (!LocksCollection.ContainsKey(Key))
                    LocksCollection.Add(Key, new object());
        }

        return LocksCollection[Key];
    }
}

Con esta nueva clase en el método para guardar web properties solo bloqueamos la property bag en la que estamos trabajando, dejando las otras webs del servidor desbloqueadas, el código queda así:
/// <summary>
/// Sets a web property to a given value. This method is thread safe.
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <param name="Value">Value to set the property to</param>
public static void SetWebProperty(this SPWeb Web, string Key, string Value)
{
    Key = Key.ToLower();
    lock (Locks.GetLock("WebPropertyWriteLock - {0}", Web.ID))
    {
        if (GetWebPropertyThreadSafe(Web, Key) != Value)
        {
            Web.Properties[Key] = Value;

            Web.Properties.Update();
        }
    }
}
Publicar un comentario

miércoles, 3 de abril de 2013

Compartiendo Datos Entre Front Ends con Thread Safe Web Properties

¿Te acuerdas en los viejos tiempos cuando solo tenías un frontend? ¿Te acuerdas cuando pensabes que era complicado?

Las cosas han cambiado y ahora para casi cualquier entorno de producción tienes unos cuantos frontents y está bien, el rendimiento mejora y, con SharePoint, es fácil meter uno más si te parece que vas corto pero también ha llevado algunas tareas a un nuevo nivel de complejidad.

Hay software por ahí como AppFabric que te permite persistir datos y compartirlos entre todos tus servidores. AppFabric es bueno pero... ¿Vas a instalar y configurar todo en todos los servers para compartir un string de 10 caracteres?

Bueno, no te hace falta. Puedes usar las Web Properties de SharePoint para hacerlo. Son rápidas de leer, de escribir, de programar y no tienes que configurar nada.

Las Web Properties de SharePoint son un poco raritas a la hora de usarlas, especialmente cuando las usas en un proceso multi hilo, pero estos wrappers pueden ahorraros algún tiempo. (Yo los he usado en un par de escenarios y funcionan, pero no puedo asegurar que sean completamente seguros)

static object PropertyWriteLock = new object();

/// <summary>
/// Sets a web property to a given value. This method is thread safe.
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <param name="Value">Value to set the property to</param>
public static void SetWebProperty(this SPWeb Web, string Key, string Value)
{
    Key = Key.ToLower();
    lock (PropertyWriteLock) //It's better to have a lock just for the key we are working with.
    {
        if (GetWebPropertyThreadSafe(Web, Key) != Value)
        {
            Web.Properties[Key] = Value;

            Web.Properties.Update();
        }
    }
}

/// <summary>
/// Returns the web property with the given key. This method is thread safe.
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <returns>Returns null if not found</returns>
public static string GetWebPropertyThreadSafe(this SPWeb Web, string Key)
{
    Key = Key.ToLower();
    using (SPSite site = new SPSite(Web.Site.ID))
    {
        using (SPWeb newWeb = site.OpenWeb(Web.ID))
        {
            return newWeb.GetWebProperty(Key);
        }
    }
}

/// <summary>
/// Returns the web property with the given key.
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <returns>Returns null if not found</returns>
public static string GetWebProperty(this SPWeb Web, string Key)
{
    Key = Key.ToLower();

    return Web.Properties[Key];
}

/// <summary>
/// Removes the web property from the web
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <remarks>The web property will remain there but set to null.</remarks>
public static void RemoveWebProperty(this SPWeb Web, string Key)
{
    if (Web.Properties.ContainsKey(Key))
        Web.Properties.Remove(Key);

    Web.Properties.Update();

    if (Web.AllProperties.ContainsKey(Key))
        Web.AllProperties.Remove(Key);

    Web.Update();
}

Esto ha simplificado algunas partes de la aplicación un montón y, voy a decirlo otra vez, es rápido.

Pruébalo y me cuentas.
Publicar un comentario

martes, 2 de abril de 2013

Iterando Listas in Trozos Pequeños y Rendimiento

Hace un par de meses publiqué un post sobre esto y a modo de conclusión dije que me parecía que sería más rápido recorrer la lista entera en trozos pequeños en lugar de hacerlo todo de golpe con una query general... pues no.

He hecho un test con una lista de 100K items para ahorrarte el trabajo y dependiendo en el tamaño de los trozos puede tardar un poco más o un montón más.

Si estás usando un RowLimit pequeño (digamos 5) el numero de veces que tienes que realizar la query para traerte la lista completa puede hacer que el proceso tarde el doble o más. Si estás usando un número mayor (digamos 1000) el rendimiento será similar al que conseguimos trayendo toda la lista en una sola query.

Resumiendo, si estás buscando un número pequeño de valores y posiblemente los consigas en las primeras iteraciones de la query paginada entonces la mejora en la eficiencia será obvia, en algunos casos he notado una media de mejora del 95%, pero ten en cuenta que si estas trayéndote la lista en trozos pequeños y lo más seguro es que tengas que procesar todos los elementos de la query el proceso será más lento, hasta un 400% más lento o incluso más.
Publicar un comentario