UCMA 通用 QuestionAnswer 活动

Posted

技术标签:

【中文标题】UCMA 通用 QuestionAnswer 活动【英文标题】:UCMA Generic QuestionAnswer activity 【发布时间】:2013-02-20 22:41:52 【问题描述】:

我正在开发一个 UCMA 3.0 工作流应用程序,并试图在我们的客户管理系统中生成查询,从而允许最终用户通过语音或即时消息获取有关特定客户的数据。我想知道是否有人知道如何使用允许通用输入的 UCMA 创建通用问答活动。我知道我可以设置预期的输入和语法,但是使用双大写选项,以及最终用户知道确切的客户名称(或客户编号)的可能性,我更愿意允许用户输入姓名的一部分,然后在数据库中搜索可能符合条件的姓名列表。有谁知道一种方法,并且有示例代码可以让我这样做吗?

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,不得不编写一个自定义活动来捕获用户的通用输入。这需要一些工作才能使其生产就绪。注意 system.exception 在多个地方的经典捕获,以及如果在超时期限内未收到输入而不是重新提示用户则抛出异常。用户输入也没有正则表达式...

InstanceDependencyProperty 是另一个让 Workflow 感到沮丧的东西。如果不使用 InstanceDependencyProperties,您将无法在活动完成后检索任何结果。

希望这会有所帮助!

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading;

using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using Microsoft.Rtc.Collaboration;
using Microsoft.Rtc.Workflow.Activities;
using Microsoft.Rtc.Workflow.Common;


namespace ActivityLibrary

    public partial class CaptureIMInput : Activity, IInstanceDependencyContainer
    
        #region Private member variables
        private CallProvider _callProvider;
        private Timer _maximumTimer;
        private string _imText;
        private bool messageReceived = false;
        private bool _maximumTimerElapsed = false;
        #endregion

        public CaptureIMInput()
        
            InitializeComponent();
            _instanceDependencyProperties = new Dictionary<string, object>();
        

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        
            try
            
                this._callProvider = Utilities.GetCallProviderFromParent<InstantMessagingCall>(this);
                InstantMessagingCall call = (InstantMessagingCall)this._callProvider.Call;

                try
                

                    if (call.State == CallState.Established)
                    
                        call.Flow.EndSendInstantMessage(call.Flow.BeginSendInstantMessage(MainPrompt, null, null));
                        _maximumTimer = new Timer(new TimerCallback(OnMaximumTimerFired), null, MaximumPrompt, new TimeSpan(0, 0, 0, 0, -1));
                        call.Flow.MessageReceived += this.InstantMessagingFlow_MessageReceived;
                        while (!messageReceived)
                            
                                if (_maximumTimerElapsed)
                                    throw new TimeoutException("User input was not detected within alloted time");
                            
                        if (!string.IsNullOrEmpty(_imText))
                        
                            IMText = _imText;
                            
                                this.Stop();
                                return ActivityExecutionStatus.Closed;
                            
                        
                    

                
                catch (Exception ex)
                
                    throw ex;
                
            
            catch (Exception ex)
            
                throw ex;
            

            return ActivityExecutionStatus.Closed;
        

        protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext)
        
            this.Stop(); //Clean up timer
            return ActivityExecutionStatus.Canceling;
        

        private void Stop()
        
            if (_maximumTimer != null)
            
                _maximumTimer.Dispose();
                _maximumTimer = null;
            
        

        private void InstantMessagingFlow_MessageReceived(object sender, InstantMessageReceivedEventArgs e)
        
            //Can't set dependencyproperties directly from sub-thread
            _imText = e.TextBody;
            //Mark bool so main while loop exits
            messageReceived = true;
        

        //Callback to 
        private void OnMaximumTimerFired(object state)
        
            _maximumTimerElapsed = true;
        


        #region InstanceDependency dictionary
        private Dictionary<string, object> _instanceDependencyProperties;
        [Browsable(false)]
        public Dictionary<string, object> InstanceDependencyProperties
        
            get  return _instanceDependencyProperties; 
        
        #endregion

        #region Maximum Prompt Timeout
        [NonSerialized]
        private static readonly InstanceDependencyProperty MaximumPromptProperty = InstanceDependencyProperty.Register("MaximumPrompt", typeof(TimeSpan), typeof(CaptureIMInput), new TimeSpan(0, 0, 30));

        [TypeConverter(typeof(TimeSpanConverter))]
        public TimeSpan MaximumPrompt
        
            get
            
                if (base.DesignMode)
                    return (TimeSpan)InstanceDependencyHelper.GetValue<CaptureIMInput>(this, MaximumPromptProperty);
                else
                    return (TimeSpan)InstanceDependencyHelper.GetValue<CaptureIMInput>(this, this.WorkflowInstanceId, MaximumPromptProperty);
            
            set
            
                if (base.DesignMode)
                    InstanceDependencyHelper.SetValue<CaptureIMInput>(this, MaximumPromptProperty, value);
                else
                    InstanceDependencyHelper.SetValue<CaptureIMInput>(this, this.WorkflowInstanceId, MaximumPromptProperty, value);
            
        
        #endregion

        #region MainPrompt
        public static DependencyProperty MainPromptProperty =
            DependencyProperty.Register("MainPrompt", typeof(string), typeof(CaptureIMInput));

        [ValidationOption(ValidationOption.Required)]
        public string MainPrompt
        
            get
            
                return (string)base.GetValue(MainPromptProperty);
            
            set
            
                base.SetValue(MainPromptProperty, value);
            
        
        #endregion

        #region Instant Message Text
        public static InstanceDependencyProperty IMTextProperty =
            InstanceDependencyProperty.Register("IMText",
                typeof(string),
                typeof(CaptureIMInput));

        [Description("InstantMessaging Text from user")]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string IMText
        
            get
            
                if (base.DesignMode) return ((string)InstanceDependencyHelper.GetValue<CaptureIMInput>(this, CaptureIMInput.IMTextProperty));
                else return ((string)(InstanceDependencyHelper.GetValue<CaptureIMInput>(this, this.WorkflowInstanceId, CaptureIMInput.IMTextProperty)));
            
            set
            
                if (base.DesignMode) InstanceDependencyHelper.SetValue<CaptureIMInput>(this, CaptureIMInput.IMTextProperty, value);
                else InstanceDependencyHelper.SetValue<CaptureIMInput>(this, this.WorkflowInstanceId, CaptureIMInput.IMTextProperty, value);
            
        
        #endregion

    

【讨论】:

以上是关于UCMA 通用 QuestionAnswer 活动的主要内容,如果未能解决你的问题,请参考以下文章

Flutter-不可为空的实例字段'questionAnswer','questionText'必须初始化

UCMA 3.0 示例学习项目

在 UCMA 中取消转移

使用 UCMA 4.0 的呼叫队列方法

UCMA设置lync在线状态

我可以使用 UCMA 3.0 以编程方式建立视频通话吗?