Как настроить WCF для поддержки FaultContracts, когда и хост, и клиент находятся в одном и том же процессе с использованием net.pipe?
Я пытаюсь создать внутрипроцессный модульный тест для взаимодействия моего сервиса с клиентом, используя привязку net.pipe. Как и хороший сервис WCF, он использует FaultContractAttribute в операциях службы для выявления возможных сбоев (исключений в оболочке ) для метаданных. Я хотел бы настроить конечные точки клиента и службы с помощью XML (App.config). Однако всякий раз, когда выдается ошибка, это просто CommunicationException "канал закрыт", а не типизированная ошибка, которую я ожидал.
System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).
Я попытался добавить конечную точку IMetadataExchange для net.pipe, но это не сработало. Я тоже попробовал. То, что на Vista, потребовало от меня netsh ACL для конечной точки http. Это тоже не сработало.
Класс пользовательских исключений:
public class ValidationException : ApplicationException { }
Это последняя попытка конфигурации, но она выдает "Имя контракта IMetadataExchange не найдено в списке контрактов, реализованных сервисом"
Будем благодарны за любые ссылки на примеры или рекомендации, как это сделать.
<system.serviceModel>
<client>
<endpoint name="Client"
contract="IService"
address="net.pipe://localhost/ServiceTest/"
binding="netNamedPipeBinding"
bindingConfiguration="netPipeBindingConfig" />
</client>
<services>
<service
name="Service"
behaviorConfiguration="ServiceFaults">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/ServiceTest/"/>
<add baseAddress="http://localhost/ServiceTest/"/>
</baseAddresses>
</host>
<endpoint
address=""
binding="netNamedPipeBinding"
bindingConfiguration="netPipeBindingConfig"
name="ServicePipe"
contract="IService" />
<endpoint
address="MEX"
binding="mexNamedPipeBinding"
bindingConfiguration="mexNetPipeBindingConfig"
name="MexUserServicePipe"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<netNamedPipeBinding>
<binding name="netPipeBindingConfig"
closeTimeout="00:30:00"
sendTimeout="00:30:00" />
</netNamedPipeBinding>
<mexNamedPipeBinding>
<binding name="mexNetPipeBindingConfig"></binding>
</mexNamedPipeBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceFaults">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<behavior name="MEX">
<serviceMetadata
httpGetEnabled="true"
httpGetUrl="http://localhost/ServiceTest/MEX"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
4 ответа
Если описанный выше класс ValidationException является классом, который вы используете для ошибок, он может быть источником вашей проблемы. Вы должны получить свои исключения ошибок из FaultException, потому что он сериализуем. ApplicationException не является.
Вагнер прав, вам нужно украсить свое определение операции атрибутом FaultContract, указав тип контракта. Вы также должны украсить свой FaultContract с атрибутами DataContract и DataMember.
И последнее, что нужно добавить. Определяют ли ваши операционные контракты ServiceFault, который они используют?
Насколько я понимаю, вы должны определить, какие ServiceFaults вы используете на уровне операций, и ваша бизнес-логика выдает исключение FaulException, где T - это ServiceFault, который вы определили.
Я получил ту же ошибку несколько дней назад.
Я решил создать свой собственный класс (MyFault) и выбросить FaultException с сервера и перехватить их в клиенте. MyFault имеет строковый член, который является сообщением об исключении, которое я хочу видеть клиенту.
Надеюсь, я дал понять... Я постараюсь найти хороший образец и выложу его здесь
Проблема, скорее всего, заключается в ошибке десериализации или сериализации запроса или ответа. Включите трассировку и просмотрите журнал с помощью svctraceviewer для точной ошибки.
Также убедитесь, что ваше исключение ошибки помечено [DataContract] и не наследует классы, отличные от [DataContract].