Ответ 1
Посмотрите IExtensibleDataObject, он используется для обработки различных версий веб-службы, которые все еще могут общаться друг с другом. Таким образом, контракты не должны точно соответствовать. Надеюсь, это поможет.
При обновлении служебной ссылки моего 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
для работы.
Спасибо заранее.
Посмотрите IExtensibleDataObject, он используется для обработки различных версий веб-службы, которые все еще могут общаться друг с другом. Таким образом, контракты не должны точно соответствовать. Надеюсь, это поможет.
Во-первых, я замечаю, что вы пытаетесь связать 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>
Проверьте App.Config
и убедитесь, что он указывает на ваш развернутый хост службы Windows или установите для него значение localhost
.
В чем вы говорите, кажется, что вашему новому сервису 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"
Я не думаю, что вы полностью отключили безопасность. Попробуйте следующее:
<bindings>
<wsHttpBinding>
<binding name="NoSecurityBinding" >
<security mode="None">
<transport clientCredentialType="None"/>
<message clientCredentialType="None"/>
</security>
</binding>
<binding name="DefaultBinding" />
</wsHttpBinding>
</bindings>
Существующий параметр web.config может создать проблему, как и для предыдущей версии. Лучше удалить существующую ссылку из вашего клиентского приложения WCF и снова добавить ссылку.
<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>