Подтвердить что ты не робот

Несоответствие ContractFilter в EndpointDispatcher (обработка ошибок)

При обновлении служебной ссылки моего WCF-клиента (просто щелкнув ссылку Обновление сервисной справки в Visual Studio 2008), возникает следующая ошибка:

System.ServiceModel.FaultException: Сообщение с действием 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Get' не могут быть обработаны в приемнике, из-за несоответствия ContractFilter на EndpointDispatcher. Это может быть из-за несоответствия контракта (несогласованные действия между отправителем и приемник) или привязка/безопасность несоответствие между отправителем и получатель. Убедитесь, что отправитель и получатель имеет тот же контракт и та же привязка (включая безопасность требования, например. Сообщение, транспорт, Никто). в System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(Exception e, Сообщение)

Фон:

Я создал класс ErrorServiceBehaviour. Поскольку такое поведение создается для обработки ошибок, реализация IErrorHandler должна применяться к каждому ChannelDispatcher.

public class ErrorServiceBehaviour : Attribute, IServiceBehavior
{
   ...
   public Type FaultType
   {
      get { return _faultType; }
      set { _faultType = value; }
   }

   public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
   {
       foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
       {
           dispatcher.ErrorHandlers.Add(new ErrorHandler(_faultType));
       }
   }
}

public class ErrorHandler : IErrorHandler
{
     public ErrorHandler(Type faultType)
     {
        _faultType = faultType;         
     }
     ...
}

Позже я использовал это поведение, применив атрибут ErrorServiceBehavior к моему классу сервиса:

[ErrorServiceBehavior(FaultType = typeof(MyServiceFault))] 
public class MyService : IMyService
{
   ...
}

Дело в том, что когда я комментирую цикл foreach внутри метода ApplyDispatchBehavior, я получаю ошибку no, но это не выход (потому что я хочу, чтобы мои ошибки обрабатываться).

Ниже приведен мой сервис config:

<system.serviceModel>
    <services>
        <service behaviorConfiguration="DefaultBehavior" name="MyService">
            <endpoint address="" binding="wsHttpBinding" contract="IMyService" bindingConfiguration="NoSecurityBinding"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="DefaultBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <wsHttpBinding>
            <binding name="NoSecurityBinding" >
                <security mode="None">
                    <transport clientCredentialType="None"/>
                    <message establishSecurityContext="false"/>
                </security>
            </binding>
            <binding name="DefaultBinding" />
        </wsHttpBinding>
    </bindings>
</system.serviceModel>

Может кто-нибудь мне помочь?

UPDATE

Код, показанный ранее:

foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
    dispatcher.ErrorHandlers.Add(new ErrorHandler(_faultType));
}

добавляет настраиваемую обработку ошибок для всех конечных точек, включая метаданные. Но на самом деле это не источник проблемы - даже когда я отключу добавление обработки ошибок для конечной точки метаданных, проблема все равно возникает.

Другое уведомление: когда я изменяю bindingConfiguration первой конечной точки на DefaultBinding, у меня есть no ошибка:

<services>
    <service behaviorConfiguration="DefaultBehavior" name="MyService">
        <endpoint address="" binding="wsHttpBinding" contract="IMyService" bindingConfiguration="DefaultBinding"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
</services>

Такой вариант тоже не то, что я хочу - мне все еще нужно проблемное NoSecurityBinding для работы.

Спасибо заранее.

4b9b3361

Ответ 1

Посмотрите IExtensibleDataObject, он используется для обработки различных версий веб-службы, которые все еще могут общаться друг с другом. Таким образом, контракты не должны точно соответствовать. Надеюсь, это поможет.

Ответ 2

Во-первых, я замечаю, что вы пытаетесь связать mexHttpBinding с конечной точкой, хотя она никогда не была определена внутри вашего тега "Bindings". Это должно вызвать исключение, и я ожидаю, что такое исключение будет похоже на то, что вас беспокоит.

 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

...

<bindings>
    <mexHttpBinding>
        THIS TAG WAS MISSING (add security features as needed)
    </mexHttpBinding>

    <basicHttpBinding>
        <binding name="NoSecurityBinding" >
            <security mode="None" />
        </binding>
        <binding name="DefaultBinding" />
    </basicHttpBinding>
</bindings>

Кроме того, поскольку вы, очевидно, не нуждаетесь в какой-либо функции безопасности, вам может потребоваться поддержка basicHttpBinding. Как сказано в очень тщательном ответе, wsHttpBinding действительно полезно, когда вам нужны функции безопасности.

Ваша конфигурация будет почти одинаковой, изменив "ws" на "basic".

<system.serviceModel>
<services>
    <service behaviorConfiguration="DefaultBehavior" name="MyService">
        <endpoint address="" binding="basicHttpBinding" contract="IMyService" bindingConfiguration="NoSecurityBinding"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
</services>
<behaviors>
    <serviceBehaviors>
        <behavior name="DefaultBehavior">
            <serviceMetadata httpGetEnabled="true" />
            <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
    </serviceBehaviors>
</behaviors>
<bindings>
    <basicHttpBinding>
        <binding name="NoSecurityBinding" >
            <security mode="None" />
        </binding>
        <binding name="DefaultBinding" />
    </basicHttpBinding>
</bindings>

Ответ 3

Проверьте App.Config и убедитесь, что он указывает на ваш развернутый хост службы Windows или установите для него значение localhost.

Ответ 4

В чем вы говорите, кажется, что вашему новому сервису WCF требуется защита, а в NoSecurityBinding вы отключите его. Один из способов проверить, чтобы локально получить файл WSDL, если он есть: http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd или http://schemas.xmlsoap.org/ws/2004/09/policy или что-то подобное в импорте. Я уверен, что обновленная служба WCF включена с поддержкой безопасности


Обновление 1

Чтобы лучше понять вашу проблему, вы можете использовать трассировку WCF. Здесь вы можете увидеть, как включить его и как читать эти трассы: "Как включить трассировку WCF"

Ответ 5

Я не думаю, что вы полностью отключили безопасность. Попробуйте следующее:

<bindings>
        <wsHttpBinding>
            <binding name="NoSecurityBinding" >
                <security mode="None">
                    <transport clientCredentialType="None"/>
                    <message clientCredentialType="None"/>
                </security>
            </binding>
            <binding name="DefaultBinding" />
        </wsHttpBinding>
    </bindings>

Ответ 6

Существующий параметр web.config может создать проблему, как и для предыдущей версии. Лучше удалить существующую ссылку из вашего клиентского приложения WCF и снова добавить ссылку.

Ответ 7

<services>
  <service behaviorConfiguration="ServiceBehaviour" name="Service">
    <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="IService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>