martes, 24 de julio de 2012

Item Event Receivers en SharePoint Services 3.0

Acabo de pasar una de esas situaciones en las que un componente desarrollado por mi pasa bien por las pruebas en el ambiete de desarrollo y al momento de llevarlo a producción aparecen errores que uno no esperaba y peor aún no entiende. En mi caso fué con un Item Event Handler de SharePoint Services 3.0

Desarrolle un manejador de eventos para el evento ItemDeleted y para llevarlo a producción copie el archivo .dll de mi código lo puse en el Assemblies folder, luego hice los archivos Feature.xml y Elements.xml y hasta aquí todo bien. Puse esos archivos en el panal (SharePoint Hive) y utilizando la herramienta stsadm en la consola de comandos instalé mi Feature.

Pude ver mi Feature en el sitio en donde lo instalé pero al momento de dar clic en el botón para activar boom! error.

Aquí el "descriptivo" mensaje de error:


Input string was not in a correct format.   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int32.Parse(String s, NumberStyles style, IFormatProvider provider)
   at Microsoft.SharePoint.SPEventReceiverDefinitionCollection.GetOneEventReceiverFromXml(Object[,] receivers, Int32 i, XmlNode receiverXml)
   at Microsoft.SharePoint.SPEventReceiverDefinitionCollection.GetEventReceiversFromXml(XmlNodeList receiversXml, SPEventHostType hostType, Int32& count, Object& receivers)
   at Microsoft.SharePoint.SPEventReceiverDefinitionCollection.GetFeatureEventReceivers(Int32& count, Object& receivers)
   at Microsoft.SharePoint.SPEventReceiverDefinitionCollection.EnsureEventReceivers()
   at Microsoft.SharePoint.SPEventReceiverDefinitionCollection.get_Count()
   at Microsoft.SharePoint.SPEventReceiverDefinitionCollection.GetSqlToAddEventReceiversToList(SPList list, Byte[] sourceId, SPEventReceiverSource sourceType)
   at Microsoft.SharePoint.SPEventElement.UpdateEventReceiversForList(SPWeb web, SPSqlCommand sqlcmdAppendOnly, GetSqlToUpdateEventReceivers getSqlToUpdateEventReceivers)
   at Microsoft.SharePoint.SPEventElement.ElementActivated(SPFeaturePropertyCollection props, SPSqlCommand sqlcmdAppendOnly, SPWebApplication webApp, SPSite site, SPWeb web, Boolean fForce)
   at Microsoft.SharePoint.Administration.SPElementDefinitionCollection.ProvisionContentTypeAndEventReceiverBindings(SPFeaturePropertyCollection props, SPSite site, SPWeb web, Boolean fForce)
   at Microsoft.SharePoint.Administration.SPElementDefinitionCollection.ProvisionElements(SPFeaturePropertyCollection props, SPWebApplication webapp, SPSite site, SPWeb web, Boolean fForce)
   at Microsoft.SharePoint.SPFeature.ProvisionElements(SPFeaturePropertyCollection props, SPWebApplication webapp, SPSite site, SPWeb web, Boolean fForce)
   at Microsoft.SharePoint.SPFeature.Activate(SPSite siteParent, SPWeb webParent, SPFeaturePropertyCollection props, Boolean fForce)
   at Microsoft.SharePoint.SPFeatureCollection.AddInternal(Guid featureId, SPFeaturePropertyCollection properties, Boolean force, Boolean fMarkOnly)
   at Microsoft.SharePoint.SPFeatureCollection.Add(Guid featureId)
   at Microsoft.SharePoint.WebControls.FeatureActivator.BtnActivateFeature_Click(Object objSender, EventArgs evtargs)
   at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

No tengo la menor remota idea de que se trata este error, busqué en google como todo buen desarrollador responsable de su código pero no enconté nada que me diera una luz. Luego me decidí por llamarles por teléfono a dos buenos compañeros, excelentes desarrolladores para Dynamics CRM y uno de ellos (JLAGG) me hizo ver algo que no había contemplado al inicio porque me irrité y me fuí inmediatamente a buscar solución: sí el error sucede al intentar activar, entonces el problema no esta en el código del assembly (el archivo .dll) sino que debe de estar en alguno de los archivos xml (Feature, Elements)... claro! (vean en el error la parte que puse en negrita, es una función que al parecer sirve para tomar elementos para el Feature y que lee los datos extraídos de algún archivo xml el cual puede ser el Elements.xml). 

Aquí el código de mis archivos xml.

xml version="1.0" encoding="utf-8" ?>
<Feature Scope="Web"
            Title="Server ICF Deleting Event Handler"
            Description="Deletes all related Server CIs from Server ICF at its deletion"
            Id="ECA9EDD7-B30B-4eee-8E46-3D19AFE7928F"
            Hidden="FALSE"
            xmlns="http://schemas.microsoft.com/sharepoint/">
      <ElementManifests>
            <ElementManifest Location="Elements.xml"/>
      ElementManifests>
Feature>


/////////////////////////////////////////////////////////////////////////////

      <Receivers ListTemplateId="100">
            <Receiver>
                  <Name>ICF Event ReceiversName>
                  <Type>ItemDeletedType>
                  <SequenceNumber>SequenceNumber>
                  <Assembly>ICF_EventReceivers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxxxx Assembly>
                  <Class>ICF_EventReceivers.ServerICFHandlerClass>
                  <Data>Data>
                  <Filter>Filter>
            Receiver>                  
      Receivers>
Elements>

Arriba pueden ver el código de ambos, el primero corresponde al Feature.xml y el siguiente a Elements.xml en caso de que no lo hubieran notado.

Sin dar tanto rodeo el error esta en el tag <SequenceNumber><SequenceNumber> el cual no tiene valor alguno, porque lo hice así? bueno pues porque obedientemente seguí un código que encontré donde no pusieron ese valor.

Solo se que este número determina la secuencia de ejecución del Receiver, esto es porque en un sitio pueden haber varios Event Recievers y es por esto que es necesario poner un valor.

Después de poner 1000 como valor y haberlo intentado activar todo funcionó bien.
Morajela: no sigan obedientemente todos los pasos en los blogs que ven, hay que analizar un poco el código ;-)