¿Cómo configura WCF para admitir FaultContracts donde el host y el cliente están en el mismo proceso usando un net.pipe?

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

Pregunta

Estoy tratando de crear una prueba de unidad en proceso para mi servicio a las interacciones del cliente usando el enlace net.pipe. Al igual que un buen servicio WCF, utiliza FaultContractAttribute en las operaciones de servicio para exponer posibles fallas (excepciones envueltas) a los metadatos. Me gustaría tener el cliente y los puntos finales de servicio configurados a través de XML (App.config). Sin embargo, cada vez que se genera una falla, es solo una tubería de CommunicationException '' cerrada '', y no la falla escrita. Estaba esperando.

System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d). 

Intenté Agregar punto final IMetadataExchange para net.pipe, pero eso no funcionó. Yo también lo intenté. El hecho de estar en Vista requería que netsh la ACL para el punto final http. Eso tampoco funcionó.

La clase de excepción personalizada:

public class ValidationException : ApplicationException { }

Este es el último intento de configuración, pero no se puede encontrar " El nombre del contrato 'IMetadataExchange' no se pudo encontrar en la lista de contratos implementados por el servicio "

Cualquier enlace a ejemplos o recomendaciones sobre cómo hacer esto sería apreciado.

<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>

¿Fue útil?

Solución

Si la clase ValidationException que describe anteriormente es la clase que está utilizando para fallas, puede ser la fuente de su problema. Debe derivar sus excepciones de fallas de FaultException porque es serializable. ApplicationException no lo es.

Wagner tiene razón, debe decorar su definición de operación con un atributo FaultContract que le da el tipo de contrato. También debe decorar su FaultContract con los atributos DataContract y DataMember también.

Otros consejos

Recibí el mismo error hace unos días.
Resolví creando mi propia clase (MyFault) y lanzando FaultException desde el servidor y capturándolos en el cliente. MyFault tiene un miembro de cadena que es el mensaje de excepción que quiero que vea el cliente.

Espero haberme aclarado ... Intentaré buscar una buena muestra y la publicaré aquí

El problema es probablemente un error deserializando o serializando la solicitud o respuesta. Habilite el rastreo y vea el registro con svctraceviewer para ver el error exacto.

Además, asegúrese de que su excepción de error esté marcada con [DataContract] y no herede ni clases [DataContract].

Una última cosa para agregar. ¿Sus contratos de operación definen el ServiceFault que están utilizando?

Tengo entendido que tiene que definir qué valores de servicio que está usando en la capa de operación, y su lógica de negocios arroja una FaulException donde T es el valor de servicio que definió.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top