Créer un Formulaire Web (ASP.NET) connecté à Dynamics CRM

 

Dans le projet qui suit, nous voulons mettre à disposition d’internautes un formulaire de prise de contact, via lequel ils pourront nous soumettre un projet.

Nous voulons que l’envoi de ce formulaire génère un enregistrement dans Dynamics CRM.
Pour le formulaire de saisie, nous visons cette présentation:

Formulaire Saisie

Deux types d’intégration de ces informations peuvent être envisagés :

  1. Envoyer les informations collectées dans le formulaire par email à un contact (plusieurs niveaux d’intégration et de sélection du destinataire peuvent être envisagés). Cette option est abordée ici .
  2.  Créer directement un enregistrement dans Dynamics CRM 2013.

C’est sur ce deuxième cas que porte cet article, puisqu’il permet d’initier un enregistrement CRM et très vite d’utiliser les fonctions de Dynamics CRM dans la suite du processus.

Pré-requis :

Les éléments nécessaires sont les suivants:

  • (Une organisation Dynamics CRM Online activée).
  • Visual Studio 2012 ou 2013
  • Un compte Windows Azure  (une version d’évaluation peut être  activée ici)
  • Le Windows Azure SDK (téléchargeable ici)
  • Le SDK Dynamics CRM

Analyse des Données attendues: Choix de l’entité de destination

Puisque les personnes soumettant leurs demandes peuvent être de nouveaux contacts inconnus de la base client, nous décidons d’utiliser l’entité “Prospects” (Lead) de Dynamics CRM comme receptacle des données du formulaire.

Cette entité porte nativement des informations de contact, de société, ainsi que divers champs permettant de qualifier un projet: Description, Délai de décision, …

Nous commençons donc par analyser les champs que nous voulons voir renseignés quand une demande est formulée via le portail Web.

Image

nous notons pour cet exercice les champs suivants:

  • Sujet
  • Prénom (du Contact)
  • Nom (du Contact)
  • téléphone (du Contact)
  • Email (du Contact)
  • Nom de La société (qui permettra notamment de vérifier si la société est déjà cliente)
  • Budget
  • Date de fermeture estimée (que l’on considèrera être la date de prise de décision du client par défaut)
  • Délai d’exécution d’achat ( qui renseigne un ordre de grandeur horizon pour la prise de décision)

Analyse des exigences de la page Web:

Les formats de champs utilisés:

Parmi les champs sollicités, certains sont de simples champs texte, d’autres sont des listes de valeur ou des dates. Le format de chaque champs doit être identifié car il devra le cas échéant afficher des valeurs de choix issues du CRM, mais  surtout, envoyer des données compatibles avec le format de Destination ( celui du champs CRM qui doit être alimenté).

Ce dialogue avec Dynamics CRM (ou tout autre application) suppose une part de code “Serveur” qui nécessite d’accéder:

  1. à la bonne organisation (parceque l’on est poli…)
  2. d’être authentifié (parceque c’est mieux quand ça marche)

A ce stade, le futur environnement de la page Web qui  va porter ce formulaire doit être pris en compte:

le code serveur, qui se manifeste sous forme de fichier “.dll”,  est un incontournable, or certains sites Web comme SharePoint Online, qui est une plateforme mutualisée, ne tolèrent pas les DLL externes.

Cela amène à deux solutions de contournement:

  • Soit nous utilisons du code HTML complété par du Javascript
  • Soit nous développons la page en ASP.NET,  mais il faudra alors l’héberger en dehors de SharePoint Online et l’intégrer ensuite sous forme de Composant WebPart.

Pour cet exercice, nous optons pour la deuxième solution.

Création du Projet Page Web en ASP.NET

Vous pouvez partir d’un projet vide mais le SDK CRM 2013 présente l’avantage de proposer un projet “WebAppWalkthrough” qui porte une structure par défaut.

Image

Dans Visual Studio 2013 (ou autre version) , ouvrez ce projet existant ou créez le votre

Créez les champs du formulaire dans la page aspx

Pour le formulaire évoqué plus haut, nous utilisons ce code:

Formulaire ASP Design

<%@PageTitle=”Home Page”Language=”C#”MasterPageFile=”~/Site.master”AutoEventWireup=”true”CodeBehind=”Default.aspx.cs”Inherits=”WebAppWalkthrough._Default”%>

<asp:ContentID=”HeaderContent”runat=”server”ContentPlaceHolderID=”HeadContent”>

</asp:Content>

<asp:ContentID=”BodyContent”runat=”server”ContentPlaceHolderID=”MainContent”>

Merci de renseigner les informations suivantes:

<br/>

<br/>

Prénom:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtFirstName”runat=”server”></asp:TextBox>

<br/>

<br/>

Nom:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtName”runat=”server”></asp:TextBox>

<br/>

<br/>

Email&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtEmail”runat=”server”TextMode=”Email”></asp:TextBox>

&nbsp;<br/>

<br/>

Telephone:&nbsp;

<asp:TextBoxID=”txtTel”runat=”server”TextMode=”Phone”Height=”25px”></asp:TextBox>

<br/>

<br/>

Nom de la Société:<br/>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtCompanyName”runat=”server”Width=”300px”></asp:TextBox>

<br/>

<br/>

Objet :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtSujet”runat=”server”Width=”450px”></asp:TextBox>

<br/>

<br/>

Description du projet: ;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtDescription”runat=”server”Height=”150px”TextMode=”MultiLine”Width=”500px”></asp:TextBox>

<br/>

<br/>

Budget:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtBudget”runat=”server”></asp:TextBox>

<br/>

 

Récupération des Valeurs de l’horizon : pour l’horizon, nous devons récupérer une liste  de Valeurs du CRM (objet DropDown)

Horizon :&nbsp;&nbsp;&nbsp;

<asp:DropDownListID=”ddlHorizon”runat=”server”>

</asp:DropDownList>

<br/>

Récupération d’une date de décision : pour la date de decision, nous utilisons un objet “calendar”

Date de décision (si connue):

<asp:CalendarID=”Calendar1″runat=”server”></asp:Calendar>

<br/>

<asp:ButtonID=”btnSave”runat=”server”OnClick=”btnSave_Click”Text=”Envoyer mon projet”/>

</asp:Content>

Remarque:

Si besoin, ajoutez les champs utiles dans le fichier Xrm.cs en identifiant leur nom technique dans Dynamics CRM

Exemple : purchase timeframe

Type : Groupe d’Option

Exemple Purchase Timeframe

Add Purchase Timeframe

Add Purchase Timeframe Zoom

Equivalences de champs dans le CodeBehind

Faites ensuite les équivalences dans l’onglet Codebehind (cs) :

  • Déclarez les paramètres de connexion à l’organisation ainsi que l’utilisateur choisi pour se connecter:

{

CrmConnection cnx = CrmConnection.Parse(“Url=https:// VOTREORGANISATION.crm4.dynamics.com; Username=USER@ VOTREORGANISATION.com; Password=USER PASSWORD;”);

IOrganizationService service = newOrganizationService(cnx);

  • Effectuez le mapping associant le champ de formulaire et le champ CRM (ici lead.* propose les champs du prospect que l’on associe aux champs du formulaire)

Xrm.Lead lead = new Xrm.Lead();

lead.FirstName = txtFirstName.Text;

lead.LastName = txtName.Text;

lead.Description = txtDescription.Text;

lead.CompanyName = txtCompanyName.Text;

lead.MobilePhone = txtTel.Text;

lead.BudgetAmount = Decimal.Parse(txtBudget.Text);

lead.EstimatedCloseDate = newDateTime();

service.Create(lead);

Focus sur les formats:

  • Si vous utilisez un champ texte pour la mention d’un montant, il est recommandé d’ajouter une condition de vérification de donnée pour éviter tout incident de « lecture », exemple une condition vérifiant que le champ est renseigné: if (txtBudget.Text.Length > 0)
  • la valeur saisie doit ensuite être convertie dans un format qui sera compatible avec celui du champ de destination dans Dynamics CRM. La fonction « Parse » effectue cette action de conversion en décimale, en date, etc. :

Exemple:

{

lead.BudgetAmount = Decimal.Parse(txtBudget.Text);

}

  • De même pour les champs texte renseignant une Date: si vous avez utilisé un champ texte pour saisir la date ( et non un calendrier comme dans notre exemple), il faut convertir la saisie en date:

lead.EstimatedCloseDate = DateTime.Parse(txtDateDecision.Text);

  • Pour les valeurs de listes, il faut récupérer la liste et sélectionner la valeur qui nous intéresse (les valeurs d’option ont le plus souvent un identifiant technique et un libellé)

publicstaticList<OptionItem> GetGlobalOptionsetValues(string optionsetName, IOrganizationService service)

{

List<OptionItem> values = newList<OptionItem>();

var optionsetSelectedText = string.Empty;

var retrieveOptionSetRequest = newRetrieveOptionSetRequest { Name = optionsetName };

var retrieveOptionSetResponse = (RetrieveOptionSetResponse)service.Execute(retrieveOptionSetRequest);

var retrievedOptionSetMetadata = (OptionSetMetadata)retrieveOptionSetResponse.OptionSetMetadata;

var optionList = retrievedOptionSetMetadata.Options.ToArray();

foreach (OptionMetadata optionMetadata in optionList)

{

values.Add(newOptionItem() { Value = optionMetadata.Value.Value, Text = optionMetadata.Label.UserLocalizedLabel.Label });

Une fois ces équivalences finalisées, la solution peut être généré.

Script Final:

Dans notre exemple, pour plus de facilité dans la reconnaissance des formats, nous avons décidé de ne reposer que sur la saisie du calendrier pour la mention de la date de décision. Le script est le suivant:

Default.aspx :

<%@PageTitle=”Home Page”Language=”C#”MasterPageFile=”~/Site.master”AutoEventWireup=”true”CodeBehind=”Default.aspx.cs”Inherits=”WebAppWalkthrough._Default”%>

<asp:ContentID=”HeaderContent”runat=”server”ContentPlaceHolderID=”HeadContent”>

</asp:Content>

<asp:ContentID=”BodyContent”runat=”server”ContentPlaceHolderID=”MainContent”>

Merci de renseigner les informations suivantes:

<br/>

<br/>

Prénom:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtFirstName”runat=”server”></asp:TextBox>

<br/>

<br/>

Nom:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtName”runat=”server”></asp:TextBox>

<br/>

<br/>

Email&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtEmail”runat=”server”TextMode=”Email”></asp:TextBox>

&nbsp;<br/>

<br/>

Telephone:&nbsp;

<asp:TextBoxID=”txtTel”runat=”server”TextMode=”Phone”Height=”25px”></asp:TextBox>

<br/>

<br/>

Nom de la Société:<br/>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtCompanyName”runat=”server”Width=”300px”></asp:TextBox>

<br/>

<br/>

Objet :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtSujet”runat=”server”Width=”450px”></asp:TextBox>

<br/>

<br/>

Description du projet: ;<br/>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtDescription”runat=”server”Height=”150px”TextMode=”MultiLine”Width=”500px”></asp:TextBox>

<br/>

<br/>

Budget:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<asp:TextBoxID=”txtBudget”runat=”server”></asp:TextBox>

<br/>

<br/>

Horizon :&nbsp;&nbsp;&nbsp;

<asp:DropDownListID=”ddlHorizon”runat=”server”>

</asp:DropDownList>

<br/>

<br/>

Date de décision (si connue):

<br/>

<asp:CalendarID=”Calendar1″runat=”server”></asp:Calendar>

<br/>

<br/>

<br/>

<asp:ButtonID=”btnSave”runat=”server”OnClick=”btnSave_Click”Text=”Envoyer mon projet”/>

</asp:Content>

Default.aspx.cs :

using Microsoft.Xrm.Client;

using Microsoft.Xrm.Client.Services;

using Microsoft.Xrm.Sdk;

using Microsoft.Xrm.Sdk.Messages;

using Microsoft.Xrm.Sdk.Metadata;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace WebAppWalkthrough

{

publicclassOptionItem

{

publicint Value { get; set; }

publicstring Text { get; set; }

}

publicpartialclass_Default : System.Web.UI.Page

{

IOrganizationService service = null;

privatevoid ConnectToCRM()

{

CrmConnection cnx = CrmConnection.Parse(“Url=https:// VOTREORGANISATION.crm4.dynamics.com; Username=USER@ VOTREORGANISATION.com; Password=USER PASSWORD;”);

service = newOrganizationService(cnx);

}

protectedvoid Page_Load(object sender, EventArgs e)

{

// purchasetimeframe

if (!Page.IsPostBack)

{

ConnectToCRM();

var horizonValues = GetGlobalOptionsetValues(“purchasetimeframe”, service);

ddlHorizon.DataSource = horizonValues;

ddlHorizon.DataTextField = “Text”;

ddlHorizon.DataValueField = “Value”;

ddlHorizon.DataBind();

}

}

protectedvoid btnSave_Click(object sender, EventArgs e)

{

ConnectToCRM();

Xrm.Lead lead = new Xrm.Lead();

lead.FirstName = txtFirstName.Text;

lead.LastName = txtName.Text;

lead.Subject = txtSujet.Text;

lead.Description = txtDescription.Text;

lead.CompanyName = txtCompanyName.Text;

lead.MobilePhone = txtTel.Text;

if (txtBudget.Text.Length > 0)

{

lead.BudgetAmount = Decimal.Parse(txtBudget.Text);

}

lead.PurchaseTimeFrame = int.Parse(ddlHorizon.SelectedValue.ToString());

lead.EstimatedCloseDate = Calendar1.SelectedDate;

service.Create(lead);

}

protectedvoid txtName2_TextChanged(object sender, EventArgs e)

{

}

publicstaticList<OptionItem> GetGlobalOptionsetValues(string optionsetName, IOrganizationService service)

{

List<OptionItem> values = newList<OptionItem>();

var optionsetSelectedText = string.Empty;

var retrieveOptionSetRequest = newRetrieveOptionSetRequest { Name = optionsetName };

var retrieveOptionSetResponse = (RetrieveOptionSetResponse)service.Execute(retrieveOptionSetRequest);

var retrievedOptionSetMetadata = (OptionSetMetadata)retrieveOptionSetResponse.OptionSetMetadata;

var optionList = retrievedOptionSetMetadata.Options.ToArray();

foreach (OptionMetadata optionMetadata in optionList)

{

values.Add(newOptionItem() { Value = optionMetadata.Value.Value, Text = optionMetadata.Label.UserLocalizedLabel.Label });

}

Mise à disposition :

Ce projet a été conçue pour un site Web ASP.NET, il peut donc être hébergé dans une page Web ASP.NET Azure par exemple.
Nous exposons la procédure à suivre ici:

#asp-net, #azure-2