Службы Appfabric WF4-WCF, как получить текущий URL-адрес в кодовой активности без httpcontext?

Я разработал службы wf-wcf с активностью кода, и в ней я хочу получить текущий URL-адрес службы. Если я отключу функцию сохранения в appfabric, я могу получить URL-адрес, используя

HttpContext.Current.Request.Url.ToString()

Если функция сохраняемости включена, httpcontext имеет значение null.

Есть ли другой способ получить URL-адрес WCF, в котором размещается моя активность кода?


person tartafe    schedule 04.05.2010    source источник


Ответы (1)


Вам необходимо внедрить IReceiveMessageCallback и добавить это к контексту деятельности. В OnReceiveMessage вы передаете текущий OperationContext, что позволяет вам проверять входящее сообщение.

В этом образце WF4 показано, как это сделать.

Пример кода:

using System.Activities;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activities;

namespace DeclarativeServiceLibrary2
{
    public sealed class GetWCFMessageTo : NativeActivity
    {
        public Receive Receive { get; set; }

        public OutArgument<string> WcfTo { get; set; }

        protected override void Execute(NativeActivityContext context)
        {
            context.Properties.Add("ReceiveMessageCallback", new ReceiveMessageCallback());
            context.ScheduleActivity(Receive, CompletionCallback);
        }

        private void CompletionCallback(NativeActivityContext context, ActivityInstance completedInstance)
        {
            var receiveMessageCallback = context.Properties.Find("ReceiveMessageCallback") as ReceiveMessageCallback;
            WcfTo.Set(context, receiveMessageCallback.WcfRequestTo);
        }
    }

    [DataContract]
    class ReceiveMessageCallback : IReceiveMessageCallback
    {
        public string WcfRequestTo { get; private set; }

        public void OnReceiveMessage(OperationContext operationContext, ExecutionProperties activityExecutionProperties)
        {
            WcfRequestTo = operationContext.RequestContext.RequestMessage.Headers.To.ToString();
        }
    }
}

и пример рабочего процесса XAMLX

<WorkflowService mc:Ignorable="sap" ConfigurationName="Service1" sap:VirtualizedContainerService.HintSize="307,306" Name="Service1" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:d="clr-namespace:DeclarativeServiceLibrary2;assembly=DeclarativeServiceLibrary2" 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://tempuri.org/" xmlns:p1="http://schemas.microsoft.com/netfx/2009/xaml/activities" 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:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <p1:Sequence DisplayName="Sequential Service" sad:XamlDebuggerXmlReader.FileName="c:\temp\DeclarativeServiceLibrary2\DeclarativeServiceLibrary2\Service1.xamlx" sap:VirtualizedContainerService.HintSize="277,276" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">
    <p1:Sequence.Variables>
      <p1:Variable x:TypeArguments="CorrelationHandle" Name="handle" />
      <p1:Variable x:TypeArguments="x:Int32" Name="data" />
      <p1:Variable x:TypeArguments="x:String" Name="WcfRequestTo" />
    </p1:Sequence.Variables>
    <sap:WorkflowViewStateService.ViewState>
      <scg3:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">True</x:Boolean>
      </scg3:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <d:GetWCFMessageTo sap:VirtualizedContainerService.HintSize="255,22" WcfTo="[WcfRequestTo]">
      <d:GetWCFMessageTo.Receive>
        <Receive x:Name="__ReferenceID0" CanCreateInstance="True" DisplayName="ReceiveRequest" sap:VirtualizedContainerService.HintSize="255,90" OperationName="GetData" ServiceContractName="p:IService">
          <Receive.CorrelationInitializers>
            <RequestReplyCorrelationInitializer CorrelationHandle="[handle]" />
          </Receive.CorrelationInitializers>
          <ReceiveMessageContent>
            <p1:OutArgument x:TypeArguments="x:Int32">[data]</p1:OutArgument>
          </ReceiveMessageContent>
        </Receive>
      </d:GetWCFMessageTo.Receive>
    </d:GetWCFMessageTo>
    <SendReply Request="{x:Reference __ReferenceID0}" DisplayName="SendResponse" sap:VirtualizedContainerService.HintSize="255,90">
      <SendMessageContent>
        <p1:InArgument x:TypeArguments="x:String">["Received " &amp; data &amp; " WCF To header: " &amp; WcfRequestTo]</p1:InArgument>
      </SendMessageContent>
    </SendReply>
  </p1:Sequence>
</WorkflowService>
person Maurice    schedule 04.05.2010
comment
У меня два вопроса по поводу этого подхода: 1) этот подход подходит только для NativeActivity, верно? 2) в примере метод OnReceiveMessage не имеет возвращаемого значения, и я не понимаю, как я могу вернуть URL-адрес действия. - person tartafe; 05.05.2010
comment
Вы добавляете OutArgument к действию и используете его в своем рабочем процессе. См. Пример кода в обновленном ответе - person Maurice; 05.05.2010
comment
оно работает! большое спасибо. В целом этот подход более сложен, чем другие, используемые, например, в wf 3.5 во время выполнения MOSS. Я надеюсь, что как можно скорее будет разработана более удобная встроенная функция или упростится весь фреймворк в целом, представив, например, окружающий контекст, на данный момент я надеюсь, чем такие люди, как вы, помогут новичку вроде меня :) - person tartafe; 05.05.2010
comment
@Maurice есть ли возможность использовать интерфейс IReceiveMessageCallback с Receive активностью, доступной в дизайнере? - person shashwat12; 21.04.2015