<Activity mc:Ignorable="sap" x:Class="DocApprovalProcessLib.DocApprovalProcess" sap:VirtualizedContainerService.HintSize="483,1422" mva:VisualBasic.Settings="Assembly references and imported namespaces for internal implementation" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:e="clr-namespace:Extensions;assembly=Extensions" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:s4="clr-namespace:System;assembly=System.ServiceModel" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:ssa="clr-namespace:System.ServiceModel.Activities;assembly=System.ServiceModel.Activities" xmlns:ssx="clr-namespace:System.ServiceModel.XamlIntegration;assembly=System.ServiceModel" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Sequence DisplayName="文档审批流程" sad:XamlDebuggerXmlReader.FileName="e:\zhengyi\visual studio 2010\Projects\CtripSZ.WFPlatform\DocApprovalProcessLib\DocApprovalProcess.xaml" sap:VirtualizedContainerService.HintSize="443,1382"> <Sequence.Variables> <Variable x:TypeArguments="x:Int64" Name="ProcessInstanceID"/> <Variable x:TypeArguments="p:CorrelationHandle" Name="__handle1"/> <Variable x:TypeArguments="p:CorrelationHandle" Name="ProcessInstanceHandle"/> </Sequence.Variables> <sap:WorkflowViewStateService.ViewState> <scg3:Dictionary x:TypeArguments="x:String, x:Object"> <x:Boolean x:Key="I***panded">True</x:Boolean> </scg3:Dictionary> </sap:WorkflowViewStateService.ViewState> <Pick DisplayName="文档创建" sap:VirtualizedContainerService.HintSize="421,858"> <PickBranch DisplayName="用户发起了一个新申请" sap:VirtualizedContainerService.HintSize="307,812"> <PickBranch.Trigger> <p:Receive x:Name="__ReferenceID0" CanCreateInstance="True" DisplayName="收到用户的消息" sap:VirtualizedContainerService.HintSize="277,100" OperationName="CreateProcessInstance" ServiceContractName="IDocApprovalService"> <p:Receive.CorrelationInitializers> <p:RequestReplyCorrelationInitializer CorrelationHandle="[__handle1]"/> </p:Receive.CorrelationInitializers> </p:Receive> </PickBranch.Trigger> <Sequence DisplayName="新申请响应" sap:VirtualizedContainerService.HintSize="277,598"> <sap:WorkflowViewStateService.ViewState> <scg3:Dictionary x:TypeArguments="x:String, x:Object"> <x:Boolean x:Key="I***panded">True</x:Boolean> </scg3:Dictionary> </sap:WorkflowViewStateService.ViewState> <Assign DisplayName="产生流程实例编号" sap:VirtualizedContainerService.HintSize="255,57"> <Assign.To> <OutArgument x:TypeArguments="x:Int64">[ProcessInstanceID]</OutArgument> </Assign.To> <Assign.Value> <InArgument x:TypeArguments="x:Int64">[DateTime.Now.ToFileTimeUtc()]</InArgument> </Assign.Value> </Assign> <e:PromoteValue x:TypeArguments="x:Int64" ClearExistingPromotedData="False" sap:VirtualizedContainerService.HintSize="255,22" Name="ProcessInstanceID" Value="[ProcessInstanceID]"/> <p:InitializeCorrelation Correlation="[ProcessInstanceHandle]" sap:VirtualizedContainerService.HintSize="255,90"> <InArgument x:TypeArguments="x:String" x:Key="Id">[ProcessInstanceID.ToString()]</InArgument> </p:InitializeCorrelation> <p:SendReply Request="{x:Reference __ReferenceID0}" DisplayName="SendReplyTo收到用户的消息" sap:VirtualizedContainerService.HintSize="255,86"> <p:SendMessageContent DeclaredMessageType="x:Int64"> <InArgument x:TypeArguments="x:Int64">[ProcessInstanceID]</InArgument> </p:SendMessageContent> </p:SendReply> <WriteLine DisplayName="输出信息" sap:VirtualizedContainerService.HintSize="255,59" Text="[String.Format("A 'DocApprovalProcess' instance ({0}) has been created.", ProcessInstanceID)]"/> </Sequence> </PickBranch> </Pick> <Pick DisplayName="文档审批" sap:VirtualizedContainerService.HintSize="421,360"> <PickBranch DisplayName="经理审批" sap:VirtualizedContainerService.HintSize="285,314"> <PickBranch.Variables> <Variable x:TypeArguments="x:String" Name="action"/> <Variable x:TypeArguments="x:String" Name="comment"/> <Variable x:TypeArguments="x:Int64" Name="approveID"/> </PickBranch.Variables> <PickBranch.Trigger> <p:Receive CorrelatesWith="[ProcessInstanceHandle]" DisplayName="经理审批" sap:VirtualizedContainerService.HintSize="255,100" OperationName="SupervisorApprove" ServiceContractName="IDocApprovalService"> <p:Receive.CorrelatesOn> <p:XPathMessageQuery x:Key="Id"> <p:XPathMessageQuery.Namespaces> <ssx:XPathMessageContextMarkup> <x:String x:Key="xgSc">http://tempuri.org/</x:String> </ssx:XPathMessageContextMarkup> </p:XPathMessageQuery.Namespaces>sm:body()/xgSc:SupervisorApprove/xgSc:Id</p:XPathMessageQuery> </p:Receive.CorrelatesOn> <p:ReceiveParametersContent> <OutArgument x:TypeArguments="x:Int64" x:Key="Id">[approveID]</OutArgument> <OutArgument x:TypeArguments="x:String" x:Key="action">[action]</OutArgument> <OutArgument x:TypeArguments="x:String" x:Key="comment">[comment]</OutArgument> </p:ReceiveParametersContent> </p:Receive> </PickBranch.Trigger> <WriteLine DisplayName="打印消息" sap:VirtualizedContainerService.HintSize="255,100" Text="[String.Format("Process {0} approved. Action : {1}, Comment :{2}", ProcessInstanceID, action, comment)]"/> </PickBranch> </Pick> </Sequence> </Activity>
namespace Extensions { public class CustomWorkflowServiceHostFactory : WorkflowServiceHostFactory { protected override WorkflowServiceHost CreateWorkflowServiceHost(Activity activity, Uri[] baseAddresses) { return base.CreateWorkflowServiceHost(activity, baseAddresses); } protected override WorkflowServiceHost CreateWorkflowServiceHost(WorkflowService service, Uri[] baseAddresses) { var host = base.CreateWorkflowServiceHost(service, baseAddresses); return host; } } }
- 新建一个WCF应用程序项目,添加对如下dll的引用:Extensions.dll、DocApprovalProcessLib.dll(定义了WF4 xaml工作流的活动库)、System.Activities、System.Activities.Core.Presentation、System.Activities.DurableInstancing、System.Activities.Presentation、System.ServiceModel.Activities、System.Runtime.DurableInstancing
<%@ ServiceHost Language="C#" Debug="true" Service="DocApprovalProcessLib.DocApprovalProcess" Factory="Extensions.CustomWorkflowServiceHostFactory" %>
- 如此,即完成了WF4活动库在普通WCF中的寄宿,可以右击svc文件选择“在浏览器中查看”来检查
2. 接下来,我们需要对这个svc提供出来的WF4服务来进行配置,换句话说,就是要在web.config中配置出WF4持久化等相关特性。
首先,我们来回顾一下通过程序方式寄宿WF4服务和持久化的实现,我们需要通过配置来达到相同的效果
//工作流服务寄宿 var host = new WorkflowServiceHost( new DocApprovalProcessLib.DocApprovalProcess(), new Uri("http://localhost:8080/DAP")); //增加默认终结点和元数据终结点 host.AddDefaultEndpoints(); host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true }); host.AddServiceEndpoint("IMetadataExchange", MetadataExchangeBindings.CreateMexHttpBinding(), "mex"); //增加工作流服务持久化配置 var store = new SqlWorkflowInstanceStore("Data Source=HP580DBSZ\\DEVDBINSTANCE;Initial Catalog=WorkflowDB;Integrated Security=True;"); host.DurableInstancingOptions.InstanceStore = store; //异常过滤 host.UnknownMessageReceived += (o, e) => { Console.WriteLine("\n" + e.Message + "\n"); }; //扩展流程数据存储 host.Description.Behaviors.Add(new WorkflowIdleBehavior() { TimeToPersist = TimeSpan.FromSeconds(0) }); XNamespace xNS = PromotionPersistenceParticipant.PromotedPropertyXNamespace; store.Promote("DocApprovalProcess", new List<XName> { xNS.GetName("ProcessInstanceID") }, null); //host.WorkflowExtensions.Add(new Extensions.InstanceStoreParticpant()); host.WorkflowExtensions.Add(new Extensions.PromotionPersistenceParticipant()); //启动工作流服务 host.Open();
- 3. 之前提到我们定义了不同的PromoteValue<T> CodeActivity,有一系列的类来支持在配置中初始化CodeActivity,我们同样把它们定义在Extensions项目中,依次列出:
SqlWorkflowInstanceStorePromotionBehavior,继承自ystem.ServiceModel.Activities.Description.SqlWorkflowInstanceStore,扩展WF4服务的数据库持久化行为
namespace Extensions { public class SqlWorkflowInstanceStorePromotionBehavior : SqlWorkflowInstanceStoreBehavior, IServiceBehavior { public SqlWorkflowInstanceStorePromotionBehavior(string connectionString) : base(connectionString) { } internal SqlWorkflowInstanceStorePromotionBehavior(SqlWorkflowInstanceStoreBehavior sqlWorkflowInstanceStoreBehavior) { base.ConnectionString = sqlWorkflowInstanceStoreBehavior.ConnectionString; base.HostLockRenewalPeriod = sqlWorkflowInstanceStoreBehavior.HostLockRenewalPeriod; base.InstanceCompletionAction = sqlWorkflowInstanceStoreBehavior.InstanceCompletionAction; base.InstanceEncodingOption = sqlWorkflowInstanceStoreBehavior.InstanceEncodingOption; base.InstanceLockedExceptionAction = sqlWorkflowInstanceStoreBehavior.InstanceLockedExceptionAction; base.RunnableInstancesDetectionPeriod = sqlWorkflowInstanceStoreBehavior.RunnableInstancesDetectionPeriod; } public SqlWorkflowInstanceStorePromotionBehavior() { } public new void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { if (serviceHostBase == null) { throw new ArgumentNullException("serviceHostBase"); } WorkflowServiceHost workflowServiceHost = serviceHostBase as WorkflowServiceHost; if (workflowServiceHost != null) { workflowServiceHost.WorkflowExtensions.Add<PromotionPersistenceParticipant>(() => new PromotionPersistenceParticipant()); } base.ApplyDispatchBehavior(serviceDescription, serviceHostBase); } public void Promote(string name, IEnumerable<string> promoteAsSqlVariant, IEnumerable<string> promoteAsBinary) { XNamespace xNS = PromotionPersistenceParticipant.PromotedPropertyXNamespace; List<XName> sqlVariantPromotions = null; List<XName> binaryPromotions = null; if (promoteAsSqlVariant != null) { sqlVariantPromotions = new List<XName>(); foreach (string propertyName in promoteAsSqlVariant) { sqlVariantPromotions.Add(xNS.GetName(propertyName)); } } if (promoteAsBinary != null) { binaryPromotions = new List<XName>(); foreach (string propertyName in promoteAsBinary) { binaryPromotions.Add(xNS.GetName(propertyName)); } } base.Promote(name, sqlVariantPromotions, binaryPromotions); } } }
- PromotionPersistenceParticipant通用自定义流程数据的工作流持久性参与者,继承自System.Activities.Persistence.PersistenceParticipant,相当于系列练习中的InstanceStoreParticpant
-
namespace Extensions { public class PromotionPersistenceParticipant : PersistenceParticipant { public static XNamespace PromotedPropertyXNamespace = XNamespace.Get("http://ctripsz.com/persistence/SqlWorkflowInstanceStorePromotions"); Dictionary<XName, object> promotedProperties; public PromotionPersistenceParticipant() { this.promotedProperties = new Dictionary<XName, object>(); } public void AddPromotedVariable(string variableName, object variableValue) { this.promotedProperties[PromotedPropertyXNamespace.GetName(variableName)] = variableValue; } public void ClearExistingPromotionData() { this.promotedProperties.Clear(); } ///<summary> /// 这个方法会在工作流实例被持久化的时候自动调用 /// 这些数据是会被保存到InstancePromotedPropertiesTable这个表的 ///</summary> ///<param name="readWriteValues"></param> ///<param name="writeOnlyValues"></param> protected override void CollectValues(out IDictionary<XName, object> readWriteValues, out IDictionary<XName, object> writeOnlyValues) { readWriteValues = null; writeOnlyValues = this.promotedProperties; } } }
PromoteValue<T>,这个就是我们自定义的CodeActivity了,它定义了一个供持久化参与者使用的键值对
namespace Extensions { public class PromoteValue<T> : CodeActivity { public bool ClearExistingPromotedData { get; set; } public string Name { get; set; } public InArgument<T> Value { get; set; } ///<summary> /// 如果活动返回值,则从 CodeActivity派生并从 Execute 方法返回该值 ///</summary> ///<param name="context"></param> protected override void Execute(CodeActivityContext context) { var extension = context.GetExtension<PromotionPersistenceParticipant>(); if (extension != null && this.Name != null && this.Value != null) { if (this.ClearExistingPromotedData) { extension.ClearExistingPromotionData(); } T propertyValue = context.GetValue<T>(this.Value); extension.AddPromotedVariable(this.Name, propertyValue); } } } }
- 额外的PromoteValues,也是一个CodeActivity,相当于PromoteValue<T>的一个集合
-
namespace Extensions { public class PromoteValues : CodeActivity { public PromoteValues() { this.ValuesToPromote = new Dictionary<string, InArgument>(); } public bool ClearExistingPromotedData { get; set; } public IDictionary<string, InArgument> ValuesToPromote { get; set; } ///<summary> /// 如果活动返回值,则从 CodeActivity派生并从 Execute 方法返回该值 ///</summary> ///<param name="context"></param> protected override void Execute(CodeActivityContext context) { PromotionPersistenceParticipant persistenceParticipant = context.GetExtension<PromotionPersistenceParticipant>(); if (persistenceParticipant != null) { if (this.ClearExistingPromotedData) { persistenceParticipant.ClearExistingPromotionData(); } foreach (KeyValuePair<string, InArgument> promotedProperty in ValuesToPromote) { string propertyName = promotedProperty.Key; object propertyValue = promotedProperty.Value != null ? promotedProperty.Value.Get(context) : null; persistenceParticipant.AddPromotedVariable(propertyName, propertyValue); } } } } }
SqlWorkflowInstanceStorePromotionElement,对应SqlWorkflowInstanceStorePromotionBehavior,继承自System.ServiceModel.Activities.Configuration.SqlWorkflowInstanceStoreElement(又继承自BehaviorExtensionElement),用于支持在配置文件中配置SqlWorkflowInstanceStorePromotionBehavior服务行为扩展
namespace Extensions.Configuration { public class SqlWorkflowInstanceStorePromotionElement : SqlWorkflowInstanceStoreElement { public override Type BehaviorType { get { return typeof(SqlWorkflowInstanceStorePromotionBehavior); } } [ConfigurationProperty("promotionSets", IsDefaultCollection = false)] public PromotionSetsCollection PromotionSets { get { return (PromotionSetsCollection)base["promotionSets"]; } } protected override object CreateBehavior() { SqlWorkflowInstanceStorePromotionBehavior behavior = new SqlWorkflowInstanceStorePromotionBehavior((SqlWorkflowInstanceStoreBehavior)base.CreateBehavior()); foreach (PromotionSet promotionSet in this.PromotionSets) { List<string> sqlVariantProperties = new List<string>(); List<string> binaryProperties = new List<string>(); foreach (PromotedValueElement promotedValue in promotionSet) { (promotedValue.IsSqlVariant ? sqlVariantProperties : binaryProperties).Add(promotedValue.PropertyName); } behavior.Promote(promotionSet.Name, sqlVariantProperties, binaryProperties); } return behavior; } } }
- PromotionSetsCollection,SqlWorkflowInstanceStorePromotionElement的子配置项,表现到配置文件是一个XML集合节点
namespace Extensions.Configuration { public class PromotionSetsCollection : ConfigurationElementCollection { public override ConfigurationElementCollectionType CollectionType { get { return ConfigurationElementCollectionType.BasicMap; } } protected override string ElementName { get { return "promotionSet"; } } protected override ConfigurationElement CreateNewElement() { return new PromotionSet(); } protected override object GetElementKey(ConfigurationElement element) { return ((PromotionSet)element).Name; } } }
- PromotionSet,PromotionSetsCollection的子配置项,用于在配置文件中初始化一个PromoteValue<T> CodeActivity
namespace Extensions.Configuration { public class PromotionSet : ConfigurationElementCollection { public override ConfigurationElementCollectionType CollectionType { get { return ConfigurationElementCollectionType.BasicMap; } } [ConfigurationProperty("name", IsKey = true, IsRequired = true)] public string Name { get { return (string)base["name"]; } set { base["name"] = value; } } protected override string ElementName { get { return "promotedValue"; } } protected override ConfigurationElement CreateNewElement() { return new PromotedValueElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((PromotedValueElement)element).PropertyName; } } }
- PromotedValueElement,初始化PromoteValue<T> CodeActivity的属性
namespace Extensions.Configuration { public class PromotedValueElement : ConfigurationElement { public PromotedValueElement() { } [ConfigurationProperty("isSqlVariant", IsKey = false, DefaultValue = true)] public bool IsSqlVariant { get { return (bool)this["isSqlVariant"]; } set { this["isSqlVariant"] = value; } } [ConfigurationProperty("propertyName", IsRequired = true, IsKey = true)] public string PropertyName { get { return (string)this["propertyName"]; } set { this["propertyName"] = value; } } } }
- 4. 好了,定义了一堆WCF服务行为扩展,和WCF配置元素后,让我们在WCF项目的web.config中来使用它们
先在<system.serviceModel>节点下添加sqlWorkflowInstanceStorePromotion扩展WF持久化参与者
-
<extensions> <behaviorExtensions> <add name="sqlWorkflowInstanceStorePromotion" type="Extensions.Configuration.SqlWorkflowInstanceStorePromotionElement, Extensions"/> </behaviorExtensions> </extensions>
然后在<system.serviceModel>节点下配置WCf服务行为,设置workflowIdle和sqlWorkflowInstanceStorePromotion
-
<behaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> <behavior name="WorkflowBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> <workflowIdle timeToPersist="0" timeToUnload="0"/> <sqlWorkflowInstanceStorePromotion connectionStringName="WorkflowDB" hostLockRenewalPeriod="00:00:05" runnableInstancesDetectionPeriod="00:00:02" instanceCompletionAction="DeleteAll" instanceLockedExceptionAction="AggressiveRetry" instanceEncodingOption="GZip"> <promotionSets> <promotionSet name="DocApprovalProcess"> <promotedValue propertyName="ProcessInstanceID"/> </promotionSet> </promotionSets> </sqlWorkflowInstanceStorePromotion> </behavior> </serviceBehaviors> </behaviors>
最后在<system.serviceModel>下配置WCF服务终结点,这儿请一定注意,service的name必须和活动库项目中xaml文件的名称一致,例如,我的代码中是DocApprovalProcess.xaml,这儿就必须配置为DocApprovalProcess;而服务契约contract,是在xaml工作流设计中Receive活动中定义的契约名
-
<services> <service behaviorConfiguration="WorkflowBehavior" name="DocApprovalProcess"> <endpoint address="" binding="wsHttpContextBinding" bindingConfiguration="" contract="IDocApprovalService"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services>
当然,别忘记配置一个数据库连接供sqlWorkflowInstanceStorePromotion使用,你也可以在sqlWorkflowInstanceStorePromotion中改用connectionString属性直接将数据库连接字符串写到里面,而不是使用connectionStringName属性
<connectionStrings> <add name="WorkflowDB" connectionString="Data Source=HP580DBSZ\DEVDBINSTANCE;Initial Catalog=WorkflowDB;Integrated Security=True;Async=true;" providerName="System.Data.SqlClient"/> </connectionStrings>
- 5. OK,我们已经完成了所有的工作,现在到客户端中添加指向svc的服务引用,执行一下,看看客户端和数据库是否都产生了我们预期的结果吧。
WCF客户端配置
<system.serviceModel> <bindings> <basicHttpBinding> <wsHttpBinding> <binding name="WSHttpBinding_ICommonWorkflowService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default"/> </security> </binding> </wsHttpBinding> <wsHttpContextBinding> <binding name="WSHttpContextBinding_IDocApprovalService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false" contextProtectionLevel="Sign"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default"/> </security> </binding> </wsHttpContextBinding> </bindings> <client> <endpoint address="http://localhost:4292/CommonWorkflowService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICommonWorkflowService" contract="CommonWorkflowService.ICommonWorkflowService" name="WSHttpBinding_ICommonWorkflowService"> <identity> <userPrincipalName value="xxxxx"/> </identity> </endpoint> <endpoint address="http://localhost:4292/DocApprovalProcessService.svc" binding="wsHttpContextBinding" bindingConfiguration="WSHttpContextBinding_IDocApprovalService" contract="DocApprovalProcessService.IDocApprovalService" name="WSHttpContextBinding_IDocApprovalService"> <identity> <userPrincipalName value="xxxxx"/> </identity> </endpoint> </client> </system.serviceModel>
- 运行结果