2012-10-18 14 views
5

Sto costruendo un WCF in C# e un client per consumarlo allo stesso tempo. Per qualche motivo ho problemi a trovare un metodo per restituire un int. Qui è il mio contratto:WCF non restituirà un int

[ServiceContract] 
public interface IMData 
{ 
    [OperationContract] 
    int ReturnAnInt(); 

    [OperationContract] 
    String HelloWorld(); 
} 

Qui è dove ho implementato:

public class MData : IMData 
{ 
    public String HelloWorld() 
    { 
    return "Hello World"; 
    } 

    public int ReturnAnInt() 
    { 
    return 5; 
    } 
} 

sto usando Visual Studio, e per il cliente, ho importato questo WCF come un riferimento Web. Ora per qualche motivo quando dichiaro un'istanza di MData e provo a chiamare HelloWorld, non c'è alcun problema, ma ricevo un errore di compilazione quando si chiama ReturnAnInt.

MData m = new MData(); 
String helloWorld = m.HelloWorld(); 
int result = m.ReturnAnInt(); 

L'errore che ottengo con ReturnAnInt è: "No sovraccarico per il metodo 'ReturnAnInt' prende 0 argomenti" Allora ho mouse sopra per vedere cosa di Visual Studio si aspetta, e si dice che il metodo dovrebbe apparire come:

void MData.ReturnAnInt(out int ReturnAnIntResult, out bool ReturnAnIntResultSpecified) 

ho sbattere la testa contro un muro su questo per ore e che riesco a trovare nulla su Google, e ha la mia colleghi sconcertato pure. Perché ha aggiunto due parametri che non rientrano nella definizione e cambia il tipo di ritorno? Qualsiasi aiuto sarebbe molto apprezzato. Mi scuso se ho omesso qualsiasi informazione che potrebbe essere utile.

risposta

4

È possibile importarlo come riferimento di servizio (tecnologia più recente) anziché come riferimento Web (tecnologia meno recente)? Lavoro con i servizi WCF tramite riferimenti di servizio e non ho visto un problema di questo tipo: ho visto solo una proprietà Specified (e quella insieme al int, non come due parametri out) quando la definizione del servizio non consente di impostare int specificato (le definizioni del servizio generato da WCF hanno, secondo la mia esperienza, funzionato come previsto).

Se non riesci a trovare una soluzione migliore, ecco una soluzione alternativa utilizzando partial classes: (questo dovrebbe essere fatto ogni volta che si torna a struct, non solo int s)

public partial class MData 
{ 
    public int ReturnAnInt() 
    { 
     int result; 
     bool specified; 
     this.ReturnAnInt(out result, out specified); 
     if (!specified) throw new InvalidOperationException(); 
     return result; 
    } 
} 

Aggiornamentohttp://www.codeproject.com/Articles/323097/WCF-ASMX-Interoperability-Removing-the-Annoying-xx ha una soluzione (un po 'klunky) e ci informa che la causa principale è che WCF genera file WSDL poveri (probabilmente inaccurati) - hanno uno minOccurs="0" su elementi che davvero non ne hanno bisogno. Web References legge questo così com'è e genera codice klunky per gestirlo, che è ciò che stai cercando di affrontare. Sulla base di un suo articolo, è possibile restituire questo tipo invece di un int:

[MessageContract(IsWrapped = false)] 
public class MyInt 
{ 
    [MessageBodyMember] 
    public int Result { get; set; } 

    public static implicit operator MyInt(int i) 
    { 
     return new MyInt { Result = i }; 
    } 

    public static implicit operator int(MyInt m) 
    { 
     return m.Result; 
    } 
} 

Insieme con la modifica del tipo di ritorno del metodo:

[ServiceContract] 
public interface IMData 
{ 
    [OperationContract] 
    MyInt ReturnAnInt(); 

    [OperationContract] 
    String HelloWorld(); 
} 
public class Service1 : IMData 
{ 
    public MyInt ReturnAnInt() 
    { 
     return 4; 
    } 

    public string HelloWorld() 
    { 
     return "Hello World"; 
    } 
} 
+0

Vuol WCF davvero sostenere una 'parametri esterno ne? – abatishchev

+0

Sì, ma non è proprio quello di cui si tratta. Il problema descritto nella domanda è che il codice C# di WCF non specifica i parametri 'out' o' int's opzionali, ma questo è il modo in cui il generatore di codice Web References lo crea. Questo funziona. Tuttavia, è possibile definire un servizio WCF come "int ReturnAnInt (out int otherInt);" che funziona e può essere utilizzato sia come riferimento del servizio che come riferimento Web. Il WSDL generato è semplicemente un oggetto di risposta con più elementi, quindi dovrebbe generare qualcosa utilizzabile anche in altri linguaggi client. –

+0

Grazie a tutti per le vostre risposte, sono stati molto utili! L'ho importato come riferimento di servizio e il mio problema è stato risolto :) –

2

Si importa come un riferimento al servizio (con spazio dei nomi MData) invece Riferimento Web.

e utilizzare il codice qui sotto,

MDataClient m = new MDataClient(); 
String helloWorld = m.HelloWorld(); 
int result = m.ReturnAnInt(); 

Non c'è nulla di sbagliato nel codice. Dovrebbe funzionare correttamente se aggiungi Service Reference e usi lo snippet sopra riportato.

0

Avevo un problema simile, non ho potuto ottenere un parametro out int del mio servizio web per funzionare. Non sono ancora sicuro a causa di ciò che è stato esattamente, ma ho funzionato utilizzando un string come parametro out.

[OperationContract] 
LoginStatus GetLogin(string username, string password, out string s_uId); 

sul lato servizio web:

s_uId = uId.ToString(); 

sul lato client:

int uId; 
string s_uId; 
result = client.GetLogin(username, password, out s_uId); 
Int32.TryParse(s_uId, out uId); 
Problemi correlati