Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Enze Winneris

Bien coder c'est comme jouer,
suffit de savoir faire les bonnes macros !



Abonnements

CRM 4 : Migration des Callouts depuis la V3

Ca faisait longtemps que je n' avais plus posté mais maintenant je m'y remet. J'ai eu l'occasion de m'intéresser de près aux développements personnalisés sous Dynamics CRM et je vais tacher de vous faire partager mes expériences sur le sujet.

Mon premier post sur le sujet traitera de la migration puisque j'ai eu à en réaliser une sur un projet comportant des Callouts, c'est à dire des événements levés automatiquement en .NET lors de certaines actions : création/modification/suppression d'entité, changement d'état ou de propriétaire, ...

Si on regarde le SDK de la V4, on peut trouver cette phrase sur la migration des Callouts :

"Microsoft Dynamics CRM 3.0 custom extensions such as callouts and workflow assemblies that use the Microsoft Dynamics CRM 3.0 Web services can be seamlessly upgraded to Microsoft Dynamics CRM On-premise without having to recompile."

Bien évidement, cela n'a pas été aussi simple pour moi. J'ai rencontré quelques erreurs que je vais décrire ici ainsi que les solutions que j'y ai trouvé.

 

1. Erreur déclenchée dès qu'un événement Callout aurait du être levé

Optimiste, je place mon fichier XML ainsi que mes DDLs dans le dossier approprié et je teste : A chaque création d'entité, j'ai un message d'erreur type. En activant le traçage de logs sur le serveur, j'ai pu avoir un message d'erreur un peu plus explicite que le traditionnel "Veuillez contacter votre administrateur CRM". L'exception déclenchée était :

FileNotFoundException: Impossible de charger le fichier ou l'assembly 'Microsoft.Crm.Platform.Callout.Base, Version=3.0.5300.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' ou une de ses dépendances. Le fichier spécifié est introuvable.

C'est dans cette librairie que l'on trouve les prototypes des méthodes à implémenter pour en faire des Callouts donc il est normal qu'une erreur soit levée si elle n'est pas présente. Après avoir tenté d'ajouter cette assembly partout où je le pouvais, il s'est avéré que la solution était une "simple réparation" du serveur CRM à l'aide du CD d'installation de CRM.

 

2. Récupération du ColumnSet

Dans la version .NET 1, j'avais une petite méthode qui utilisait la réflexion pour obtenir la liste des attributs par type d'entités pour le paramètre du WebService.

Public Shared Function GetColumnSet(ByVal entityType As Type) As ColumnSet
    Dim cols As New ColumnSet
    Dim fields As FieldInfo() = entityType.GetFields
    Dim colNames(fields.Length - 1) As String
    For i As Integer = 0 To fields.Length - 1
        colNames(i) = fields(i).Name
    Next
    cols.Attributes = colNames
    Return cols
End Function 

Avec le .NET Framework 2 (et donc le 3 aussi), la méthode GetFields ne fonctionne plus, il faut utiliser GetProperties.

Public Shared Function GetColumnSet(ByVal entityType As Type) As ColumnSet
    Dim cols As New ColumnSet
    Dim pis As PropertyInfo() = entityType.GetProperties
    Dim colNames(pis.Length - 1) As String
    For i As Integer = 0 To pis.Length - 1
        colNames(i) = pis(i).Name
    Next
    cols.Attributes = colNames
    Return cols
End Function 

Ce n'est pas un gros changements mais l'erreur est difficile à diagnostiquer puisqu'il faut passer en debug pour voir qu'aucun attribut n'est listé par la méthode GetFields.

 

3. Distinction du type d'entité à l'aide du paramètre postImageEntityXml

Pour savoir quel type d'entité est crée/modifié/supprimé, on avait recours à un code de ce type (je rappelle qu'on ne peut toujours pas utiliser entityContext.EntityTypeCode à cause du problème des énumérations qui sont numérotées depuis 0 et par ordre alphabétique dans la référence en VB alors que les numéros CRM ne suivent pas la même logique) :

Public Overrides Sub PostCreate(ByVal userContext As CalloutUserContext, ByVal entityContext As CalloutEntityContext, ByVal postImageEntityXml As String)
    Dim de As DynamicEntity = CRMHelper.Deserialize(postImageEntityXml, GetType(DynamicEntity))
    Select Case de.Name
        Case "account"
            'Traitement pour les sociétés
        Case "contact"
            'Traitement pour les contacts
    End Select
End Sub 

Depuis le passage en version 4, j'ai pu voir en passant en debug dans la méthode que le paramètre postImageEntityXml était null, ce qui peut s'avérer gênant pour dé-sérialiser l'entité et récupérer son type. La solution est donc de faire une classe par type d'entité et de distinguer les classes à appeler au niveau du fichier XML callout.config.xml de cette façon :

<?xml version="1.0" encoding="utf-8" ?>
<callout.config version="2.0">
    <callout entity="account" event="PostCreate">
        <subscription assembly="MyCallouts.dll" class="MyCallouts.AccountCallouts"></subscription>
    </callout>
    <callout entity="contact" event="PostCreate">
        <subscription assembly="MyCallouts.dll" class="MyCallouts.ContactCallouts"></subscription>
    </callout>
</callout.config>

 

4. Récupération de l'utilisateur connecté : Utilisation du WhoAmI

Ce dernier point sort un peu du contexte des Callouts, puisqu'il s'agit d'un JavaScript permettant de récupérer l'identifiant de l'utilisateur connecté.

En CRM v3, on aurait fait comme ça :

function getUserId()
{
    try
    {
        var command = new RemoteCommand("SystemUser", "WhoAmI", "/MSCRMServices/");
        var oResult = command.Execute();
        if (oResult.Success)
            return oResult.ReturnValue.UserId;
    }
    catch(e)
    {
        alert("Error while retrieving userid.");
    }
    return null;
}

Mais en CRM v4, comme l'objet RemoteCommand n'est plus accessible, on ferait plutôt comme ça (exemple inspiré des Walkthrough du SDK) :

function getUserId()
{
    try
    {
        var serverUrl;
        if(IsOnline())
            serverUrl = "http://SRVCRM:5555";
        else
            serverUrl = "http://localhost:2525";
        var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        xmlhttp.open("POST", serverUrl  + "/mscrmservices/2007/crmservice.asmx", false);
        xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Execute");
        var soapBody = "<soap:Body>"+
            "<Execute xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+
            "<Request xsi:type='WhoAmIRequest' />"+
            "</Execute></soap:Body>";
        var soapXml = "<soap:Envelope " +
            "xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' "+
            "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "+
            "xmlns:xsd='http://www.w3.org/2001/XMLSchema'>";
        soapXml += GenerateAuthenticationHeader();
        soapXml += soapBody;
        soapXml += "</soap:Envelope>";
        xmlhttp.send(soapXml);
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async=false;
        xmlDoc.loadXML(xmlhttp.responseXML.xml);
        var userid = xmlDoc.getElementsByTagName("UserId")[0].childNodes[0].nodeValue;
        return userid;
    }
    catch(e)
    {
        alert("Error while retrieving userid.");
    }
    return null;
}

NB : N'oubliez pas de distinguer le cas Online et Offline, puisqu'en v4 on peut se servir des WebService du client comme de ceux du serveur.

 

Enze
Member of Wygteam
www.wygwam.com

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Publié mercredi 20 février 2008 10:22 par Enze

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01


Propulsé par Community Server (Personal Edition), par Telligent Systems