2012-07-05 18 views
6

favor consulte el siguiente ejemplointerfaz y una clase concreta en WCF

namespace GServices 
{ 
    [ServiceKnownType(typeof(SearchType))] 
    [ServiceContract(SessionMode = SessionMode.Allowed)] 
    public interface ITest 
    { 
     [OperationContract] 
     int subtract(int x, int y); 
    } 

    [ServiceKnownType(typeof(SearchType))] 
    [ServiceContract(SessionMode = SessionMode.Allowed)] 
    public interface ITest2 
    { 
     [OperationContract] 
     int add(int x, int y); 

    } 
    public class G : ITest2, ITest 
    { 
     public int add(int x, int y) 
     { 
      return x + y; 
     } 
     public int subtract(int x, int y) 
     { 
      return x + y; 
     } 
    } 
} 

ITest método de resta() tiene y tiene Itest2 añadir método().

Ambos son ejecutados por una clase concreta llamada G.

Si sólo quiero exponer el ITest través de WCF, he siguiente configuración de punto final

<service name="GQS1" behaviorConfiguration="GQwcfBehaviour"> 
    <endpoint address="DP2Svcs" binding="wsHttpContextBinding" bindingConfiguration="wsHttpEndpointBindingConfig" contract="GServices.itest"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    </service> 

cuando funciono este servicio y comprobar el WSDL , Puedo ver que los métodos que están en itest2 también aparecieron en wsdl. en este caso de ejemplo, el método de resta() solo debe estar expuesto. Pero el método add() también está expuesto.

Mi requisito es que los métodos en ITest Interface solo se expongan. en este caso, quiero exponer solo el método de resta() que se declara en ITest. Pero ambos de su implementación reside en Solo una clase concreta "G". ¿Que me estoy perdiendo aqui?

Editar: Yo he dado mi contenido del archivo Service.svc:

<%@ ServiceHost Language="C#" Debug="true" Service="GServices.G" %> 

enter image description here

+0

¿Cuál es el tipo de retorno de su método expuesto es que '' G 'o ITest' –

+0

@Bob: ¿No es 'int'? – abatishchev

+0

@abatishchev: bien, lo siento, copié el código de desarrollo y cambié el nombre – amaz

Respuesta

4

Asegúrese de que el valor del atributo en el elemento name<service> en la configuración es el nombre completamente calificado de la clase de servicio. En su configuración, tiene el nombre del contrato del punto final calificado por un espacio de nombre (GServices.itest), pero el servicio no es (GQS1). Si no tiene una confucación de servicio para un servicio específico, WCF agregará un punto final predeterminado que expondrá el problema que tiene. Por ejemplo, en el código siguiente, donde la línea que agrega un punto final está comentada, el WSDL en el servicio muestra ambas operaciones. Pero si descomenta la línea (lo que hará que el servicio tenga solo un punto final de tipo ITest), solo se mostrará la operación "restar".

public class StackOverflow_11339853 
{ 
    [ServiceContract(SessionMode = SessionMode.Allowed)] 
    public interface ITest 
    { 
     [OperationContract] 
     int subtract(int x, int y); 
    } 

    [ServiceContract(SessionMode = SessionMode.Allowed)] 
    public interface ITest2 
    { 
     [OperationContract] 
     int add(int x, int y); 

    } 
    public class G : ITest2, ITest 
    { 
     public int add(int x, int y) 
     { 
      return x + y; 
     } 
     public int subtract(int x, int y) 
     { 
      return x + y; 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(G), new Uri(baseAddress)); 
     // host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), ""); 
     host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true }); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
+0

Muchas gracias @carlosfigueira, me salvaste la vida. !!! Gracias de nuevo. El problema real es que tengo solo una clase concreta que implementa ambas interfaces. Si especificamos el nombre completo de la clase en la etiqueta de servicio, recibí este error: "Ya existe un elemento hijo llamado 'servicio' con la misma clave en el mismo ámbito de configuración". Lo que hice, he creado una nueva clase derivada llamada "G1" de la clase de implementación real "G" y remito este nombre en el nombre del servicio, ¡ahora está bien! muchas gracias hombre! – amaz

1

Si usted no necesita la interfaz ITest2 expuesto como un servicio, basta con quitar el atributo ServiceContract de ella.

Si necesita ITest2 en un servicio diferente, puede utilizar la herencia de interfaces para resolver este problema:

interface ITest2 
{ 
    [OperationContract] 
    int Add(int x, int y); 
} 

[ServiceContract] 
interface ITest2Service : ITest2 { } 

Uso ITest2 en el primer servicio (que también implementa ITest) y ITest2Service en el segundo servicio.

+0

Creo que OP quiere exponer un contrato de servicio por punto final. contratos por una sola clase. Suena razonable. – abatishchev

+0

Pero él dice claramente: * Solo quiero exponer el ITest a través de WCF * –

+0

@abatishchev: Solo necesito que tanto ITest como ITest2 exploten a través de WCF. Pero sus diferentes servicios. Es por eso que he puesto [ServiceContract] allí – amaz

Cuestiones relacionadas