2012-07-05 13 views
6

si prega di verificare l'esempio di seguitoDue Interfaccia e una classe concreta in 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 ha il metodo di sottrazione() e Itest2 ha metodo add().

Entrambi sono implementati da una classe concreta chiamato G.

se voglio solo per esporre l'ITest tramite WCF, ho seguito endpoint config

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

quando ho eseguito questo servizio e controllare il WSDL , Vedo che i metodi che sono in itest2 appaiono anche in wsdl. in questo esempio, il metodo sottrazione() deve essere esposto. Ma anche il metodo add() è esposto.

Il mio requisito è che i metodi in ITest Interface debbano essere esposti solo. in questo caso, voglio esporre solo il metodo sottrarre() che è dichiarato in ITest. Ma entrambi della loro implementazione risiedono in una sola classe concreta "G". Cosa mi manca qui?

Edit: ho dato la mia contenuto del file Service.svc:

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

enter image description here

+0

cosa è il tipo di ritorno del metodo esposto è '' G' o ITest' –

+0

@Bob: Non è 'int'? – abatishchev

+0

@abatishchev: ok, mi dispiace, ho copiato dal codice di sviluppo e ho cambiato il nome – amaz

risposta

4

Assicurarsi che il valore dell'attributo name nell'elemento <service> nella configurazione è il nome pienamente qualificato della classe di servizio. Nella tua configurazione hai il nome del contratto endpoint qualificato da uno spazio dei nomi (GServices.itest), ma il servizio non lo è (GQS1). Se non si dispone di alcuna configurazione del servizio per un servizio specifico, WCF aggiungerà un endpoint predefinito che esporrà il problema riscontrato. Ad esempio, nel codice seguente, dove la riga che aggiunge un endpoint è commentata, il WSDL sul servizio mostra entrambe le operazioni. Ma se disattivi la linea (che renderà il servizio con un solo endpoint di tipo ITest), verrà mostrata solo l'operazione "sottrazione".

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

Grazie mille @carlosfigueira, mi hai salvato la vita. !!! Grazie ancora. Il vero problema è che ho solo una classe concreta che implementa entrambe le interfacce. Se si specifica il nome della classe completamente qulified nel tag del servizio, ho ricevuto questo errore "Un elemento figlio denominato 'servizio' con la stessa chiave esiste già nello stesso ambito di configurazione." Quello che ho fatto, ho creato una nuova classe derivata chiamata "G1" dall'attuale classe di implementazione "G" e mi riferisco a questo nome in Nome servizio, è ok ora !!!! grazie mille amico! – amaz

1

Se non è necessario l'interfaccia ITest2 esposta come un servizio, è sufficiente rimuovere l'attributo ServiceContract da esso.

Se avete bisogno di ITest2 in un servizio diverso, è possibile utilizzare l'ereditarietà di interfaccia per risolvere questo problema:

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

[ServiceContract] 
interface ITest2Service : ITest2 { } 

Usa ITest2 nel primo servizio (che implementa anche ITest) e ITest2Service nel secondo servizio.

+0

Penso che OP voglia esporre un contratto di servizio per endpoint. contratti da una singola classe. Sembra ragionevole. – abatishchev

+0

Ma afferma chiaramente: * Voglio solo esporre l'ITest tramite WCF * –

+0

@abatishchev: Devo solo far sì che sia ITest che ITest2 siano esplosi tramite WCF. Ma i suoi servizi diversi. ecco perché ho messo [ServiceContract] lì – amaz

Problemi correlati