Magazine Internet

[WF4] Valider le Result d'une Activity

Publié le 26 juillet 2011 par Jeremy.jeanson

On m’a déjà dit une paire de fois, qu'il était impossible d'ajouter une contrainte ou de valider d'argument Result d'une Activity<TResult>, CodeActivity<TResult>... Il faudrait soi-disant ne pas utiliser ce type d'activité de base et utiliser les versions non génériques.

Désoler de briser ce mythe, cette opération est possible!

Comme pour toute opération de ce genre, cela passe par la réécriture de la méthode CacheMetadata().

Par exemple pour une activité que j'ai codée récemment (du type sensé être le plus complexe, car héritant de AsyncCodeActivity<TResult>), cela donne ceci :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.ComponentModel;
using MyMceSleep.Common;

namespace MyMceSleep.Workflow.Activities
{
    public sealed class AskUser : AsyncCodeActivity<EnumMessageBoxResult>
    {
        [RequiredArgument]
        [DefaultValue(0)]
        public InArgument<Int32> TimeConfigured { get; set; }

        /// <summary>
        /// BeginExecute Async
        /// </summary>
        /// <param name="context"></param>
        /// <param name="callback"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
        {
            Func<IMessageBoxExtension, Int32, EnumMessageBoxResult> funct = Ask;
            context.UserState = funct;

            return funct.BeginInvoke(
                context.GetExtension<IMessageBoxExtension>(),
                TimeConfigured.Get(context),
                callback,
                state);
        }

        /// <summary>
        /// EndExecute Async
        /// </summary>
        /// <param name="context"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        protected override EnumMessageBoxResult EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
        {
            Func<IMessageBoxExtension, Int32, EnumMessageBoxResult> funct = context.UserState as Func<IMessageBoxExtension, Int32, EnumMessageBoxResult>;

            return funct.EndInvoke(result);
        }

        /// <summary>
        /// Interroger l'utilisateur
        /// </summary>
        /// <param name="messageBoxExtension"></param>
        /// <param name="timeConfigured"></param>
        /// <returns></returns>
        private static EnumMessageBoxResult Ask(IMessageBoxExtension messageBoxExtension,Int32 timeConfigured)
        {
            return messageBoxExtension.Ask(timeConfigured);
        }

        /// <summary>
        /// CacheMetadata
        /// </summary>
        /// <param name="metadata"></param>
        protected override void CacheMetadata(CodeActivityMetadata metadata)
        {
            if (TimeConfigured == null)
            {
                metadata.AddValidationError(
                    new System.Activities.Validation.ValidationError(
                        "TimeConfigured must be set!",
                        false,
                        "TimeConfigured"));
            }
            else
            {
                RuntimeArgument arg = new RuntimeArgument("TimeConfigured", typeof(int), ArgumentDirection.In);
                metadata.AddArgument(arg);
                metadata.Bind(TimeConfigured, arg);
            }

            if (Result == null)
            {
                metadata.AddValidationError(
                    new System.Activities.Validation.ValidationError(
                        "Result must be set!",
                        false,
                        "Result"));
            }
            else
            {
                RuntimeArgument arg = new RuntimeArgument("Result", typeof(EnumMessageBoxResult), ArgumentDirection.Out);
                metadata.AddArgument(arg);
                metadata.Bind(Result, arg);
            } 
        }
    }
}

Comme on le voit bien dans la méthode CacheMetadata, je me suis permis de faire un test afin de forcer l'utilisateur à affecter une variable à l'argument Result.

Et bien que mon activité de base soit complexe, cela ne change rien à la validation présente sur Result.

Facile, il suffisait juste d'y penser ;)


Retour à La Une de Logo Paperblog

A propos de l’auteur


Jeremy.jeanson 1573 partages Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte