WCF OperationBehavior: ApplyDispatchBehavior не вызывается

Моя цель - создать поведение конечной точки для WCF, которое добавляет Ping() Операция к существующему договору. EndpointBehavior работает нормально, я действительно вижу добавленное Ping() операция, когда я запускаю свой сервис и использую тестовый клиент WCF. Я реализовал это поведение конечной точки следующим образом:

Конфигурация:

<configuration>
  <system.serviceModel>

    <services>
      <service name="X">
        <endpoint address="mex" kind="mexEndpoint" />
        <endpoint address="" binding="basicHttpBinding" contract="IX" 
             behaviorConfiguration="ping" />
      </service>
    </services>

    <behaviors>
      <endpointBehaviors>
        <behavior name="ping">
          <PingEndpointBehavior />
        </behavior>
      </endpointBehaviors>
    </behaviors>

    <extensions>
      <behaviorExtensions>
        <add name="PingEndpointBehavior" 
          type="Assembly.PingEndpointBehavior, Assembly, .. />
      <behaviorExtensions>
    </extensions>

  </system.serviceModel>
</configuration>

Поведение конечной точки:

public class PingEndpointBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    ...

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, 
      EndpointDispatcher endpointDispatcher)
    {
        var cd = endpoint.Contract;

        var inputMessage = new MessageDescription(...);
        var outputMessage = new MessageDescription(...); 
        // Set input/output messages correctly

        var od = new OperationDescription("Ping", cd);
        od.Messages.Add(inputMessage);
        od.Messages.Add(outputMessage);

        od.Behaviors.Add(new DataContractSerializerOperationBehavior(od));
        od.Behaviors.Add(new PingOperationBehavior());

        endpoint.Contract.Operations.Add(od);
    }

    ...
}

Поведение при работе, однако, не работает. ApplyDispatchBehavior() метод на поведение поведения никогда не вызывается, и, следовательно, мой собственный PingInvoker не используется Это приводит к не получению ответа при вызове добавленного Ping() операция по контракту.

Причина этого заключается в том, что OperationBehavior добавляется только после того, как служба уже запущена, в результате чего ApplyDispactchBehavior не звонят. Смотрите код ниже:

Поведение операции:

public class PingOperationBehavior : IOperationBehavior
{
    ...

    public void ApplyDispatchBehavior(OperationDescription od, DispatchOperation do)
    {
        do.Invoker = new PingInvoker();    
    }

    ...
}

Чешуи:

public class PingInvoker : IOperationInvoker
{
    ...

    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        outputs = new object[0];
        return Ping();
    }

    public static DateTime Ping()
    {
        return DateTime.Now;
    }

    ...
}

У любого есть идея, как я могу получить OperationBehavior правильно работать?

Замечания:

  • Должен работать для служб, размещенных в IIS (не самостоятельно)
  • За исключением добавления поведения в конфигурации (и ссылки на сборку, которая содержит поведение), я не хочу ничего менять в службе

2 ответа

У меня была такая же проблема с моим обычным поведением. Я был производным от WebHttpBehavior (который наследуется от IEndpointBehavior), но ApplyDispatchBehavior не вызывался.

Решением моей проблемы было добавление отсутствующего ключевого слова переопределения, например: public override void ApplyDispatchBehavior(...

Учебный класс PingEndPointBehavior:

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, 
  EndpointDispatcher endpointDispatcher)
{
    var cd = endpoint.Contract;

    var inputMessage = new MessageDescription(...);
    var outputMessage = new MessageDescription(...); 
    // Set input/output messages correctly

    var od = new OperationDescription("Ping", cd);
    od.Messages.Add(inputMessage);
    od.Messages.Add(outputMessage);

    od.Behaviors.Add(new DataContractSerializerOperationBehavior(od));

    var pingBehavior = new PingOperationBehavior();
    od.Behaviors.Add(pingBehavior);
    pingBehavior.ApplyDispatchBehavior(od, 
      endPointDispatcher.DispatchRuntime.Operations[od.Name]);

    endpoint.Contract.Operations.Add(od);
}
Другие вопросы по тегам