Как настроить WCF для поддержки FaultContracts, когда хост и клиент находятся в одном процессе с использованием net.pipe?

StackOverflow https://stackoverflow.com/questions/220401

Вопрос

Я пытаюсь создать внутрипроцессный модульный тест для взаимодействия моей службы с клиентом, используя привязку net.pipe.Как и хорошая служба WCF, она использует FaultContractAttribute в операциях службы, чтобы выявить возможные ошибки. (обернутые исключения) к метаданным.Я хотел бы настроить конечные точки клиента и службы через XML. (Приложение.конфигурация). Однако всякий раз, когда выдается ошибка, это просто 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>

Это было полезно?

Решение

Если описанный выше класс ValidationException — это класс, который вы используете для ошибок, он может быть источником вашей проблемы.Исключения ошибок следует получать из FaultException, поскольку они сериализуемы.ApplicationException нет.

Вагнер прав: вам нужно дополнить определение операции атрибутом FaultContract, указав тип вашего контракта.Вам также следует украсить свой FaultContract атрибутами DataContract и DataMember.

Другие советы

У меня такая же ошибка появилась несколько дней назад.
Я решил создать свой собственный класс (MyFault), выбросить FaultException с сервера и перехватить его на клиенте.MyFault имеет строковый элемент, который представляет собой сообщение об исключении, которое я хочу, чтобы клиент увидел.

Надеюсь, я ясно выразился...Я постараюсь найти хороший образец и выложу его здесь.

Проблема, скорее всего, заключается в ошибке десериализации или сериализации запроса или ответа.Включите трассировку и просмотрите журнал с помощью svctraceviewer, чтобы узнать точную ошибку.

Кроме того, убедитесь, что ваше исключение ошибки помечено [DataContract] и не наследует классы, отличные от [DataContract].

И последнее, что хотелось бы добавить.Определяют ли ваши операционные контракты ServiceFault, который они используют?

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top