Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

En gros accros de la documentation, j'ai découvert il y a peu une fonctionnalité absolument géniale de la MSDN : la possibilité d'exporter un contenu sous forme de PDF ou de fichier HTML.

Dit comme cela, ça ne semble pas extraordinaire. Dans les faits :

  1. Il faut commencer la navigation via la page suivante pour la version française :

    http://msdn.microsoft.com/fr-FR/library/export/help/?returnUrl=/fr-FR/library/ms123401

    J'ai noté qu'il arrive parfois que la version française bloque lors de l'export. Je vous encourage donc à utiliser la version anglaise :

    http://msdn.microsoft.com/en-US/library/export/help/?returnUrl=/en-US/library/ms123401

     

     

  2. On click sur le bouton « Continuer à naviguer »

     

  3. Pour chaque page on peut utiliser la barre de commande « ajouter cette page » pour l'ajouter à sa sélection

     

  4. Dès que l'on a terminé ses recherches, on peut utiliser la commande « Gérer les pages »

     

  5. Ceci permet d'arriver sur la page de gestion du document

    On peut alors trier les pages, ajouter/supprimer des chapitres. Ceci permet d'organiser les documents avant l'export HTML ou PDF.

 

  1. On exporte, on télécharge, on colle dans son Windows Phone et c'est gagné ;)

 

Personnellement, j'apprécie beaucoup cette fonctionnalité pour préparer des formations.

Nul n'est censé ignorer qu'il est déconseillé d'utiliser IIS pour un site quand ce même IIS sert pour SharePoint.

Dans la pratique, un jour ou un autre, vous serez peut-être contraint de la faire. Dans le cas où l'application hébergée est compilée en 64 bits (any cpu tournant sur le pool par défaut en 64bit), il n'y a pas de problèmes (à premier abord). Dans le cas d'une application compilée en 32bits, et donc avec un pool autorisant le 32bits, les choses se corsent.

 

De base votre site ne sera pas disponible :

Cette erreur vient du fait que le pool s'est arrêté. Quand on regarde l'observateur d'évènement, l'arrêt est dû au module « SPNativeRequestModule ».

Oh la belle blague : un module 64bits lancé avec un pool 32bits… forcément, ça ne peut pas fonctionner.

 

Pour s'en sortir, il faut donc ajouter une condition pour n'activer ce module que pour les pools 64 bits (commande qui est fournie via l'aide de nombreuses applications 32bits comme Plesk):

cd %systemroot%\system32\inetsrv\

appcmd.exe set config -section:system.webServer/globalModules /[name='SPNativeRequestModule'].preCondition:integratedMode,bitness64

 

Voilà une situation qui n'est pas nouvelle, mais qui s'avère être toujours aussi embarrassante en 2014.

Si vous avez envie d'apprendre à faire des applications Windows universelles, cela tombe bien. Microsoft organise un évènement pour vous le 24 avril:

Pour s'enregistrer, ça se passe ici :

https://vts.inxpo.com/Launch/QReg.htm?ShowKey=18934&GroupID=WP

 

Voilà une belle journée de webcasts en perceptive ;)

Pour ceux qui rencontreraient des problèmes avec Visual studio 2103, ou qui se demande s'ils peuvent sauter le pas pour leurs projets existants. Sachez qu'il existe une page recensant tous les cas connus.

Visual Studio 2013 Compatibility

En plus de la liste des éléments pris en compte, il est indiqué quel comportement va avoir Visual Studio face à tel ou tel fichier (très pratique pour anticiper les fichiers qui vont être upgradés vers un nouveau format).

Parfois un me remonte des problèmes liés à la méthode ScheduleActivity() du Context.

Les problèmes sont de deux sortes :

  • L'activité ne s'exécute pas.
  • Les activités ne s'exécutent pas dans le bon ordre.

Dans la plupart des cas, il s'agit d'une incompréhension de ce que fait exactement cette méthode et du fonctionnement du scheduler.

Dans WF, il n'y a pas à proprement parler de méthode pour exécuter une activité immédiatement. On doit systématiquement passer par le Context pour lui demander de planifier l'exécution d'une activité. Notre activité ne sera donc exécutée qu'en sortie de la méthode Execute de l'activité qui demande sa planification. Cela sous-entend que l'on peut planifier plusieurs activités à partir de la même méthode Execute().

Ex :

    protected override void Execute(NativeActivityContext context)
    {
        if ((this.branches != null) && (this.Branches.Count != 0))
        {
            CompletionCallback onCompleted = new CompletionCallback(this.OnBranchComplete);
            for (int i = this.Branches.Count - 1; i >= 0; i--)
            {
                context.ScheduleActivity(this.Branches[ i ], onCompleted);
            }
        }
    }

 

Trois activités sont bien planifiées, aucune n'a encore commencé à s'exécuter en sortie de la méthode Execute. Mais il n'y a aucune garantie que les activités seront exécutées dans l'ordre Activity1, Activity2, Activity3. Il n'est même pas certain qu'elles vont s'exécuter.

Pourquoi ?

Les raisons sont toutes simples :

  • D'autres activités ou l'une des trois activités planifiées peuvent mettre fin au workflow en cours d'exécution.
  • Certaines de ces activités sont peut-être asynchrones.
  • L'hôte peut demander l'annulation du workflow en cours d'exécution.

Si on veut contrôler l'ordre d'exécution, il faut planifier les activités une à une et attendre la fin de la précédente pour lancer la suivante.

Ex : (attention, cette séquence est fournie à titre d'exemple, elle ne peut être utilisée avec la persistance, car l'index n'est pas persisté)

/// 
/// Activity based on NativeActivity
/// 
public sealed class MySequence : NativeActivity
{
    public readonly Collection m_Activities;
    private Int32 m_Index;

    private CompletionCallback m_CompletionCallback;
    private FaultCallback m_FaultCallback;

    /// 
    /// Constructeur
    /// 
    public MySequence()
    {
        this.m_Activities = new Collection();
    }

    /// 
    /// Collection d'activités de la séquence
    /// 
    public Collection Activities
    {
        get { return this.m_Activities; }
    }

    /// 
    /// Execute
    /// 
    /// WF context
    /// 
    protected override void Execute(NativeActivityContext context)
    {
        // Initialisation
        this.m_Index = 0;

        // Caching callback delegates
        this.m_CompletionCallback = new CompletionCallback(this.MyCompletionCallback);
        this.m_FaultCallback = new FaultCallback (this.MyFaultCallback);

        // Schedule next activity
        this.ScheduleNext(context); 
    }

    /// 
    /// Schedule next activity in activities collection
    /// 
    /// 
    private void ScheduleNext(NativeActivityContext context)
    {
        if (this.m_Index < this.m_Activities.Count)
        {
            context.ScheduleActivity(
                this.m_Activities[this.m_Index],
                this.m_CompletionCallback,
                this.m_FaultCallback);

            this.m_Index++;
        }
    }

    public void MyCompletionCallback(NativeActivityContext context, ActivityInstance completedInstance)
    {
        this.ScheduleNext(context);
    }

    public void MyFaultCallback(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
    {
        throw propagatedException;
    }


    /// 
    /// Register activity's metadata
    /// 
    /// 
    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        if (this.m_Activities != null
            && this.m_Activities.Count != 0)
        {
            foreach (Activity a in this.m_Activities)
            {
                metadata.AddChild(a);
            }
        }
    }
}

Avec l'arrivée de Workflow Foundation 4, le rehosting du designer a été grandement simplifié. Il n'en reste pas moins que dans certains cas, l'exercice peut devenir périlleux. Cet article n'a pas pour vocation de faire le tour des différents problèmes rencontrés, mais de vous mettre sur les bons rails pour éviter de trop nombreux écueils.

D'expérience, j'ai constaté que le choix fait par les développeurs pour charger leurs workflows dans le designer conditionnait la totalité du code qui en découlait :

  • Complexité.
  • Maintenabilité.
  • Évolutivité.
  • …et bugs…

Pour charger une définition de workflow, le WorkflowDesigner dispose d'une méthode à 3 surcharges. Si on regarde la MSDN on obtient les informations suivantes :

  • Load() : Charge un flux de travail à partir du XAML contenu dans la propriété Text.
  • Load(Object) : Charge un flux de travail à l'instance spécifiée.
  • Load(String) : Charge un flux de travail à partir du XAML contenu dans le fichier spécifié.

En réalité, les choses sont un peu plus complexes. J'ai isolé trois cas de figure qui peuvent devenir très compliqués si on choisit mal sa surcharge :

  1. Plusieurs chargements
  2. Le chargement pour l'affichage
  3. Le chargement pour un usage poussé (tracking visuel, mise à jour dynamique…)

Chacun de ses scénarios induit un usage différent.

 

1. Plusieurs chargements

Tout d'abord, la méthode Load ne peut être utilisée qu'une seule foi pour un WorkflowDesigner, quelle que soit la surcharge utilisée. Si votre application doit charger plusieurs définitions de suite, il faudra donc oublier l'idée de ne créer qu'une instance de WorkflowDesigner.

Ceci est important, car si votre WorkflowDesigner est lié à de nombreux éléments, il faut relancer le code l'initialisant avant chaque Load.

Dans le cas d'un MVVM, la bonne pratique consiste à stocker le WorkflowDesigner dans un ViewModel. Ce ViewModel aura la responsabilité de créer une nouvelle instance à chaque chargement. Simple éficace et sans problèmes, quelle que soit la surcharge du Load utilisée.

Côté gestion des ressources et performance, il faut être prudent. Même si l'idée d'avoir une instance de ce ViewModel par définition est tentante, il faut se rappeler que les WorkflowDesigner sont gourmands en RAM. Certes, le chargement d'une définition par la méthode Load, n'est pas instantané. Mais il vaut mieux avoir un petit temps de chargement (dont la perception peut être atténuée par une petite animation WPF) qu'une application lourde et peu réactivée. D'autant que l'on évite ainsi les désagréments évoqués dans le point suivant.

 

2. Le chargement pour l'affichage

Dans le cas où votre unique objectif est d'afficher une définition de workflow, les trois surcharges se valent…. Enfin presque.

La seconde surcharge n'aime pas les DynamiqueActivity. Cela induit des comportements indésirables, tels qu'un design systématiquement réduit. On se retrouve donc bien souvent avec un beau rectangle dont on ne peut rien faire. A éviter en l'état. Il est préférable de lui fournir une Activity préalablement chargée en mémoire ou un ActivityBuilder.

La première et la troisième surcharge sont préférables.

Dans certain cas, où l'interface graphique est chargée sans être visible, il peut y avoir des bugs d'affichage. Il peut être préférable de n'utiliser que la troisième surcharge. Si vos définitions de workflow proviennent d'une base de données, il faudra donc passer par un fichier temporaire. Il n'y a malheureusement pas d'approche plus propre.

 

3. Le chargement pour un usage poussé (tracking visuel, mise à jour dynamique…)

Dans ce cas, il n'y a pas de secret. La troisième surcharge est la seule qui fonctionne :

  • Pour le tracking visuel, le debug et la map ne fonctionnent qu'avec un fichier.
  • Pour les mises à jour dynamiques, certains attributs ajoutés sur une activité ne sont pas bien interprétés tant que l'activité n'est pas enregistrée dans un fichier xaml.
  • … etc …

La troisième et dernière surcharge est donc préférable pour les scénarios avancés. Même si cela induit la création de fichiers temporaires.

Après avoir rencontré quelques problèmes avec le designer dans Visual Studio et des fichiers temporaires interceptés par un abruti d'antivirus dont je ne citerai pas le nom. J'en ai conclu que ce devait être une approche similaire qui devait être utilisée dans notre IDE favori. Après chaque modification, même si l'on n'enregistre pas notre xaml, un fichier temporaire est créé.

 

Voilà pour ce petit tour d'horizon d'une méthode qui a déjà fait suer pas mal de développeurs ;)

Avec Sharepoint Foundation, cela fait déjà 3 ou 4 fois que je trouve confronté à une incohérence entre les informations fournies par le site d'administration central. Cette fois-ci, c'est une restauration déclenchée via PowerShell qui semble mal remonter :

La commande passée était :

Restore-SPFarm -Directory "\\Monserveur\Backups\" -RestoreMethod Overwrite -BackupId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx -Force –Verbose

Et l'affichage via l'administration centrale qui indique dans le titre « qu'aucune restauration n'est en cours » et dans le détail « qu'une préparation de restauration est en cours »

 

Après investigation, la première ligne ne semble être mise à jour qu'à partir du moment où une tâche «sauvegarde/restauration » apparait dans le planificateur.

Moralité : Prudence quand vous consultez l'administration centrale.

Note : Je n'ai pas testé sur un SharePoint Server.

En voulant monter une nouvelle plateforme de démonstration Sharepoint Foundation 2013 SP1 + Office Web App 2013 SP1, je me suis retrouvé pour la 101e fois avec un problème de pré-requis :

« Fichiers Include côté serveur » et « Prise en charge du mode d'écriture manuscrite »

 

Dans le cas présent, le premier message n'est pas forcément évident. Il s'agit en fait d'une fonctionnalité qu'il faut ajouter à IIS.

 

Pour le second message, rien de bien compliqué. Il suffit d'ajouter une fonctionnalité serveur :

 

En espèrent que ce post soit utile à certains ;)

C'était une promesse du SP1 de SharePoint 2013 : « Être compatible avec Windows 2012 R2 ».

À partir d'une ISO incluant le SP1, on peut procéder normalement à l'installation des prérequis et du SharePoint Server:

 

La promesse est tenue. Seul hic, étant donné que rien n'est jamais vraiment tout rose au pays des bisounours. Aucune iso incluant SharePoint Foundation 2013 et le SP1 n'est distribuée pour le moment. Pour disposer d'un SharePoint Foundation 2013 sur Windows 2012 R2, il faudra donc encore patienter un peu.

Lors de la customisation de la MasterPage d'un SharePoint Foundation 2013, je suis tombé sur un os. Pour ne plus avoir de marges autour des pages de WebParts, et donc avoir un rendu proche de celui des wiki, j'ai codé le style suivant :

.ms-webpartPage-root { border-spacing:0 } 

Prévoyant d'autres modifications, j'ai mis le tout dans une librairie :

/Style Library/Style.css

Je voulais ajouter cette CSS à la fin du head. Sans raison apparente, mon code n'était pas pris en compte. Après plusieurs manipulations infructueuses, car non prise en charge par Sharepoint Foundation (ex :$SPurl qui a aussi besoin que l'on manipule les expressionBuilders) je suis arrivé à la solution simple et sans fioriture:

 < SharePoint:CSSRegistration name="/Style Library/Style.css" runat="server" / > 

Note : l'espace de "Style Library" est important pour que la feuille soit retrouvée.

De base, Visual Studio est malheureusement très pauvre en templates pour Workflow Foundation 4 :

  • 3 templates d'activités
  • 1 template de design.

Il y a quelques années, j'avais poussé 6 templates supplémentaires sur Skydrive dont 4 étaient aussi présents sur la galerie de Visual Studio.

Au vu du petit succès de ceux-ci, j'ai enfin pris mon courage à deux mains pour porter ces templates vers Visual Studio 2012 et 2013. Ces nouveaux templates, comme les précédents respectent les bonnes pratiques de WF4 et WF4.5. Ils comprennent donc l'écriture des metadatas.

Vous pouvez donc dès à présent en profiter via la boite à outils de gestion de vos extensions :

 

Ou si vous voulez télécharger le fichier VSIX : http://visualstudiogallery.msdn.microsoft.com/073c2a47-f666-4c84-8c7f-05b5ace26981

 

Une fois déployée, vous aurez le set de templates suivant :

 

Si tout se passe bien, je devrais publier sous peu, une extension avec des nouvelles commandes pour le designer de Workflow…

wait and see..

Pour qu'une activité expose des propriétés, deux choix s'offrent à nous :

  • Property : Une propriété CLR classique.
  • Argument : Une activité sur laquelle on définit une direction IN, OUT ou IN/OUT.

La raison pour laquelle on doit prendre l'une ou l'autre n'étant pas évidente, voici un petit récapitulatif des situations qui vous feront choisir l'une ou l'autre :

 

1. L'information est fixée lors sur design, elle ne change pas lors de l'exécution

Il faut utiliser alors une property. L'argument devant être exécuté pour fournir sa valeur, vous évitez ainsi d'utiliser inutilement trop des ressources.

 

2. L'information change lors de l'exécution

Si l'information fournie à votre activité doit être le fruit d'un travail préalable, il faut utiliser un InArgument<T> ou un InOutArgument<T>. Seuls les arguments peuvent contenir le fruit d'une Variable<T>. De la même manière, seuls les arguments peuvent interpréter une expression (Vb ou C#) lors de l'exécution.

 

3. L'information doit sortir de votre activité.

Seuls OutArgument<T> ou InOutArgument<T> peuvent sortir des valeurs de votre activité, pour que l'activité hôte de celle-ci puisse les récupérer dans une Variable<T>. On peut toujours envisager d'utiliser des ActivityFunc<T> ou ActivityAction<T>, mais ceci est vicieux et ne facilite pas la compréhension de votre activité par votre collègue (ou client) qui définit les workflows.

 

J'espère que ce petit récapitulatif vous sera utile ;)

Comment peut-on forcer une machine à changer d'état pour un état choisi?

Voilà une question qui m'est souvent posée. De base, ceci n'est pas possible « out of the box ». Certain disent qu'i il existe bien des « astuces » pour y arriver. Mais quand on y regarde bien, elles consistent presque toutes à réécrire sa propre usine à gaz pour héberger un Workflow totalement personnalisé pour l'hôte.

Pour être clair sur le sujet, pour forcer un état  il faut :

  1. Réécrire un état custom
  2. Réécrire une statemachine custom
  3. Réécrire un hôte dédié

Et à partir du moment où l'on a fait ce travail, dès que l'on voudra utiliser une fonctionnalité standard de WF, il faudra la réécrire…

Avez-vous vraiment besoin de coder votre propre Workfow Foudation, alors que Microsoft l'a déjà fait pour vous ?

Soyons claires, le titre ne reflète pas mon avis, ni même le contenu de cet article. Il ne sert qu’à attirer le chaland sur un contenu « coup de gueule ».

Depuis que je fais du .net, j’en vois et j’en entends des vertes et des pas mures sur .net et ses problèmes de performances. Dernièrement (hors contexte professionnel heureusement), j’ai été assez choqué par une situation qui ne se généralise peut-être pas encore, mais qui prend tout de même de l’ampleur : « n’utiliser que le constructeur par défaut d’une classe ».

Le framework fourmille de classes disposant de x constructeurs. Ceux-ci ne sont pas là juste pour faire beau dans le décor. Ils sont souvent destinés à une instanciation optimale.

Oui, dit comme cela, mes propos peuvent sembler étranges, et un peu old school ou totalement has been…

Cependant, quand je vois un modèle qui implémente INotifyProprtyChanged et que tout le monde utilise les accesseurs pour définir les propriétés de l’instance fraichement crée, ça me fou en rogne. Avec XAML, il ne faut donc pas s’étonner d’avoir des problèmes de performances.

Prenons une classe sans constructeurs (comme j’en vois trop) :

public class Item1 : NotifyPropertyChangedBase
{
    private Guid _id; 
    private Boolean _isRead;
    private Boolean _isStarred;

    public string Id
    {
        get { return _id; }
        set
        {
            if (_id == value) return;
            _id = value;
            RaisePropertyChanged();
        }
    }

    public Boolean IsRead
    {
        get { return _isRead; }
        set
        {
            if (_isRead == value) return;
            _isRead = value;
            RaisePropertyChanged();
        }
    }

    public Boolean IsStarred
    {
        get { return _isStarred; }
        set
        {
            if (_isStarred == value) return;
            _isStarred = value;
            RaisePropertyChanged();
        }
    }
}

Prenons une seconde classe similaire avec constructeurs :

public class Item2 : NotifyPropertyChangedBase
{
    private readonly Guid _id; 
    private Boolean _isRead;
    private Boolean _isStarred;

    public Item2() : this(Guid.NewGuid(), false, false) { }
    public Item2(Guid id) : this(id, false, false) { }

    public Item2(Guid id, bool isRead, bool isStarred)
    {
        _id = id;
        _isRead = isRead;
        _isStarred = isStarred;
    }

    public Guid Id
    {
        get { return _id; }
    }

    public Boolean IsRead
    {
        get { return _isRead; }
        set
        {
            if (_isRead == value) return;
            _isRead = value;
            RaisePropertyChanged();
        }
    }

    public Boolean IsStarred
    {
        get { return _isStarred; }
        set
        {
            if (_isStarred == value) return;
            _isStarred = value;
            RaisePropertyChanged();
        }
    }
}

L’instanciation de chacune avec les mêmes valeurs donnera ceci :

var i = new Item1{Id = id,IsRead = true, IsStarred=true};
var j = new Item2(id, true,true);

Rien de bien choquant. Si ce n’est qu’en instanciant la première classe, cela revient à écrire le code suivant :

public Item1(Guid id, bool isRead, bool isStarred)
{
    if (_id != id)
    {
        _id = id;
        RaisePropertyChanged();
    }
    if (_isRead != isRead) 
    {
        _isRead = isRead;
        RaisePropertyChanged();
    }
    if (isStarred != isStarred)
    {
        isStarred = isStarred;
        RaisePropertyChanged();
    }
}

Honnêtement, iriez-vous volontairement écrire ceci ?

Dans le cadre de projets d'intégration on-premise, j'ai eu à m'intéresser à SharePoint Foundation 2013. Bien qu'appréciant énormément le produit, je ne pas m'empêcher d'être déçus. Je résumerai les choses en 3 points :

 

1. Les manques

D'abord, il y a ces fonctionnalités de base qui me manquant cruellement :

  • Pas de Meta / taxonomie. Et donc aucune gestion centralisée des metadata d'entreprise L
  • La configuration initiale de la recherche est limitée. (Sorti de la configuration de base, rien n'est possible à partir du site de gestion, on doit passer par powershell… et encore, toutes les commandes ne sont pas disponibles… grrr !!!)
  • Pas de workflow manager, donc pas de workflow 2013 (Pourrat-on rester à vie avec des workflows 2010 ?).

     

2. Les nouveautés qui ne sont pas utilisables out of the box

Pour l'intégration on-premise, Sharepoint 2013 arrivant avec un lot de fonctionnalités nouvelles autour des « apps ». Dans un scénario entièrement on-premise on passe par des apps dites « provider-hosted ». Celles-ci ont besoin que la fonctionnalité de synchronisation des profils soit activée… fonctionnalité qui n'existe pas sur un Sharepoint Foundation.

Même avec une relation de confiance full trust entre la ferme SharePoint et les IIS des apps, on ne peut pas utiliser le template d'application de Visual Studio 2013. La solution consiste à ruser en utilisant les Claims avec une authentification Windows ou alors un provider partagé avec le SharePoint.

 

3. Conclusion

L'intégration d'apps dites « rovider-hosted » pouvant devenir un vrai cauchemar et Workflow 2013 n'étant pas pris en charge, les anciens modèles de développement / intégrations sont préférables, car plus simples. A mon sens, on commence à avoir un gros décalage en intégration sur Sharepoint Server et Sharepoint Foundation.

Bonne nouvelle pour les utilisateurs de Visual Studio 2013 et Oracle !

Les Oracle Developer Tools sont compatibles avec Visual Studio 2013. Comme souvent avec les produits oracle, la suppression de la version précédente est fortement conseillée si vous ne voulez pas avoir de problèmes.

Leur utilisation reste proche des versions précédentes (provider pour EF inclus). Quelques fonctionnalités sont mise à jour au passage.

Pour plus d'informations, ça se passe par ici

Bonne année et bon code pour cette année 2014.

Et tant qu'à faire, plein de beaux projets qui se réalisent ;)

Update : depuis le 20 décembre 2013, les ODT sont à jours et sont compatibles Visual Studio 2013

Pas de chance pour les utilisateurs des Oracle Developer Tools. Ceux-ci ne sont pas utilisables avec Visual Studio 2013 (et ceux même si on tente un enregistrement manuel, conformément à la documentation MSDN).

Après une tentative d'enregistrement manuelle, on peut juste constater dans les logs que les composants ODT ont des dépendances impossibles à résoudre, car liée à Visual Studio 2010 (ou 2012 en fonction de la version de l'ODAC testée).

ODT fonctionnant avec Visual Studio 2012, avec un peu de chance, la version 2013 ne devrait pas tarder.

Encore une fois, j’exhume un vieux code pour résoudre un problème courant… et surtout pour faire simple là où je vois des codes « qui font peur ».

Dans le cas présent, il s’agit de répondre à un message d’erreur qui arrive lorsque l’on veut modifier une Stream initialisée à partir d’un tableau de Bytes :

Memory stream is not expandable.

Ceci vient du fait que la Stream est marquée comme « non modifiable » lors de l’instanciation de la Stream. Certains préfèreront passer pas une Stream Custom, alors que la solution est simple :

Il suffit de passer par le constructeur par défaut puis d’ajouter le tableau de Bytes.

Le code :

// Code en erreur
Byte[] data= ... ;
MemoryStream stream = new MemoryStream(data, true);

Devient donc :

// Bon code
Byte[] data = ... ;
MemoryStream stream = new MemoryStream();
stream.Write(data, 0, data.Length);

Voila, simple et efficace Clignement d'œil

AllowBufferReceive est une option disponible dans les propriétés d'un service Workflow Foundation.

Elle a pour vocation de permettre la réception des messages dans le désordre, tout ne concevant les informations communiquées. Dans le monde structuré de WF, cela peut sembler totalement illogique.

En fait, cette option est à destination des services de type MSMQ. Pour un autre binding, on préférera utiliser une Parallel pour y glisser no Receive.

Donc pour résumé : évitez sauf si vous voulez empiler vos Receive pour avoir une visualisation verticale du worfklow.

Plus de Messages Page suivante »


Les 10 derniers blogs postés

- Emportez votre sélection de la MSDN dans la poche ? par Blog de Jérémy Jeanson le il y a 9 heures et 56 minutes

- [ #Office365 ] Pb de connexion du flux Yammer ajouté à un site SharePoint par Le blog de Patrick [MVP SharePoint] le il y a 15 heures et 17 minutes

- NFluent & Data Annotations : coder ses propres assertions par Fathi Bellahcene le il y a 15 heures et 25 minutes

- Installer un site ASP.net 32bits sur un serveur exécutant SharePoint 2013 par Blog de Jérémy Jeanson le 04-17-2014, 06:34

- [ SharePoint Summit 2014 ] Tests de montée en charge SharePoint par Le blog de Patrick [MVP SharePoint] le 04-16-2014, 20:44

- [ SharePoint Summit 2014 ] Bâtir un site web public avec Office 365 par Le blog de Patrick [MVP SharePoint] le 04-16-2014, 18:30

- Kinect + Speech Recognition + Eedomus = Dommy par Aurélien GALTIER le 04-16-2014, 17:17

- [ SharePoint Summit 2014 ] Une méthodologie simple pour concevoir vos applications OOTB SharePoint de A à Z par Le blog de Patrick [MVP SharePoint] le 04-16-2014, 16:51

- //Lean/ - Apprendre à faire des Apps Windows universelles par Blog de Jérémy Jeanson le 04-16-2014, 12:57

- Une culture de la donnée pour tous… par Le blog de Patrick [MVP SharePoint] le 04-16-2014, 11:00