Bonjour,
je développe actuellement un workflow pour SharePoint via Visual Studio, et je rencontre une petite difficulté.
Laissez moi vous décrire mon workflow :
Il s'agit d'un workflow de type SequentialWorkflowActivity.
Il est lancé manuellement par l'utilisateur qui ajoute un document.
la première étape consiste en la vérification de la présence des métadonnées obligatoires du document. S'il en manque, le workflow sera interrompu.
La liste des métadonnées obligatoires se trouve dans une liste SharePoint MetaCompulsory.
Ceci est donc matérialisé comme suit dans le code du workflow :
Si on entre dans la branche No, le workflow est terminé (utilisation d'une terminateActivity)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 private void onWorkflowActivated_Invoked(object sender, ExternalDataEventArgs e) { SPList MetaCompulsoryList = null; try { string test = WorkflowProperties.WebUrl; SPSite Site = new SPSite(WorkflowProperties.WebUrl); Web = Site.OpenWeb(); MetaCompulsoryList = Web.Lists[DocumentApprobation.Properties.Settings.Default.MetaCompulsoryList]; SPListItemCollection metaCompulsory = MetaCompulsoryList.Items; //Vérification des propriétés obligatoires foreach (SPListItem meta in metaCompulsory) { if ((WorkflowProperties.Item.Properties[meta.Name.ToString()] == null) || (WorkflowProperties.Item.Properties[meta.Name.ToString()].ToString() == string.Empty)) { this.hasAllProperties = false; break; } } } catch (Exception exc) { string error = exc.Message; } } Le booléen hasAllProperties est ensuite utilisé dans l'embranchement IfElseActivity private void hasProperties(object sender, ConditionalEventArgs e) { try { if (hasAllProperties) e.Result = true; else e.Result = false; } catch (Exception exc) { string error = exc.Message; } }
Sinon, on envoie un mail et on assigne une tache à un groupe d'utilisateurs. Cependant, tous les utilisateurs d'un groupe ne sont pas visés par le mail.
J'utilise donc une liste SharePoint qui va associer un dossier à un groupe d'utilisateurs et à une adresse mail générique.
J'associe une tache au groupe d'utilisateurs concerné à l'aide d'une activité CreateTask, dans la branche Yes de mon IfElseActivity.
Je récupère là aussi l'adresse mail pour l'envoi de mail dans l'activité suivante,, afin d'éviter de reproduire ma boucle.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 private void createMyTask_MethodInvoking(object sender, EventArgs e) { SPList approveMailingList = null; char[] forbiddenChar = { ';', '#', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; try { string[] folder = WorkflowProperties.Item.File.ToString().Split('/'); approveMailingList = Web.Lists[DocumentApprobation.Properties.Settings.Default.ApproveMailList]; SPListItemCollection itemsMail = approveMailingList.Items; foreach (SPListItem itemMail in itemsMail) { if (itemMail.Name.ToString().ToLower() == folder[folder.Length - 2].ToLower()) { //Récupération de l'adresse mail this.destMail = itemMail[DocumentApprobation.Properties.Settings.Default.mailColumn].ToString(); //Récupération du groupe à qui assigner la tache groupName = itemMail[DocumentApprobation.Properties.Settings.Default.groupColumn].ToString(); //Le nom du groupe doit etre transformé pour supprimer les carctères inutiles foreach (char c in forbiddenChar) { groupName = groupName.Replace(c, ' '); } groupName = groupName.Trim(); break; } } TaskId = Guid.NewGuid(); this.TaskProperties = new SPWorkflowTaskProperties(); TaskProperties.Title = DocumentApprobation.Properties.Settings.Default.taskTitle + WorkflowProperties.Item.Name; TaskProperties.AssignedTo = this.groupName; TaskProperties.Description = DocumentApprobation.Properties.Settings.Default.taskInstructions; } catch (Exception exc) { string error = exc.Message; } }
J'associe alors dans mon activité SendMail les propriétés du corps, sujet, destinataire et expéditeur. cette activité se trouve elle aussi dans la branche Yes de mon IfElseActivity.
Jusqu'ici, aucun problème. Mon workflow fonctionne très bien, le message est envoyé.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 private void sendEmail_MethodInvoking_1(object sender, EventArgs e) { try { string[] folder = WorkflowProperties.Item.File.ToString().Split('/'); eMailBody = @"<HTML> <BODY> <p>Le document " + @" <a href ="; eMailBody += WorkflowProperties.WebUrl + folder[folder.Length - 2]; eMailBody += @">" + WorkflowProperties.Item.Name + "</a> a été soumis à validation par " + WorkflowProperties.OriginatorUser.Name + ".</n></p>"; eMailBody += String.Format("<p>Ce document se trouve sur l'espace </p>"); eMailBody += String.Format("<p>Merci </p></BODY></HTML>"); eMailFrom = DocumentApprobation.Properties.Settings.Default.mailFrom; eMailSubject = String.Format("Nouveau document à approuver - {0}", WorkflowProperties.Item.Name); eMailTo = this.destMail; } catch (Exception exc) { string error = exc.Message; } }
Je veux ensuite boucler en attendant que le document soit validé par les validateurs et donc publié. lorsque son statut est à Published, la tache doit passer à 100% et complete.
J'utilise donc le code suivant pour mettre en place la boucle while:
C'est ici que je rencontre le problème :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 private void isNotApproved(object sender, ConditionalEventArgs e) { try { e.Result = taskNotCompleted; } catch (Exception exc) { string error = exc.Message; } }
en debug, je rentre bien dans l'initialisation de mon workflow, j'ai placé un breakpoint dans la méthode suivante :
qui me sert uniquement de repère pour voir si on rentre correctement dans la boucle while.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 private void isNotApproved(object sender, ConditionalEventArgs e) { try { e.Result = taskNotCompleted; } catch (Exception exc) { string error = exc.Message; } }
Je place ensuite une activité onWorkflowItemChanged avec le code suivant :
mais je ne rentre jamais dans cette méthode.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 private void onWorkflowItemChanged_Invoked_1(object sender, ExternalDataEventArgs e) { try { if (WorkflowProperties.Item.Level == SPFileLevel.Published) taskNotCompleted = false; } catch (Exception exc) { string error = exc.Message; } }
et j'ai le message d'erreur suivant dans mon Fault Handler :
J'ai cherché un peu sur le net, et cette erreur apparaît lors de l'utilisation dans le code d'un objet que SharePoint ne peut pas sérialiser, tel SPWeb. Ce qui n'est pas le cas...Type 'Microsoft.SharePoint.SPWeb' in Assembly 'Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' is not marked as serializable.
Savez vous d'où cela vient?
Merci d'avance, et désolé pour la longueur du post, mais c'est pour être précis dans ma description.
Partager