При обновлении служебной ссылки моего 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
для работы.
Спасибо заранее.