2012-03-23 14 views
5

ho creato un servizio WCF e al servizio predefinito ho aggiunto un altro contratto operazione sul DataContract principale:Operazione non supportata nel client di prova WCF

[OperationContract] 
void DoSomething(UserData data); 

poi ho qualcosa di simile (semplificato al fine di esempio) di seguito. Il problema è che anche se TUTTE le classi nella gerarchia sono decorate con DataContract e TUTTI i loro membri decorati con DataMember, quando utilizzo il Client Test WCF ha un'icona rossa che indica che "l'operazione non è supportata nel client di test WCF".

[DataContract] 
public class UserData { 
    [DataMember] 
    public uint One { get; set; } 

    [DataMember] 
    public CompositeType Extra { get; set; } 

    public UserData() { ctor. code } 
} 


[DataContract] 
public class CompositeType { 
    [DataMember] 
    public uint Two { get; set; } 

    public UserData() { ctor code } 
} 
+1

Vedo due classi con lo stesso nome, ma ne manca tipo composito, che cosa si intende per esso? Hai anche dimenticato di pubblicare la classe del tipo composito. – Silvermind

+0

Vedo che stai parlando di gerarchia. Stai implementando qualche tipo di relazione ricorsiva? Poiché ciò richiederebbe la classe ricorsivamente utilizzata per essere decorata con '[DataContract (IsReference = True)]' – Silvermind

+0

@Silvermind errore di errore mi dispiace, il 2o (già corretto) era CompositeType e non UserData. Ho anche aggiunto il parametro IsReference ai sottotipi utilizzati nel DataContract principale ma questo non risolve il problema. –

risposta

4

Aggiungere l'attributo alla classe 'UserData' [KnownType(typeof(CompositeType))]

come:

[DataContract] 
[KnownType(typeof(CompositeType))] 
public class UserData 
{ 
    [DataMember] 
    public uint One { get; set; } 

    [DataMember] 
    public CompositeType Extra { get; set; } 

    public UserData() { ctor. code } 
} 

http://msdn.microsoft.com/en-us/library/ms730167.aspx

Edit:

http://msdn.microsoft.com/en-us/library/system.operatingsystem.aspx

La classe ha un OperatingSystem poche proprietà che si riferiscono ad altre classi. Potresti includere tutte queste classi nei tipi noti, ma la catena delle dipendenze potrebbe diventare piuttosto grande e consiglio vivamente di non utilizzare affatto la classe del sistema operativo.

Si dovrebbe calcolare quali informazioni sono effettivamente necessarie dalla classe Sistema operativo e creare il proprio DTO per ritrasferire la risposta. In questo modo puoi assicurarti che tutti i tipi siano facilmente definibili sul tuo contratto.

+0

Ho aggiunto la decorazione KnownType al tipo genitore per indicare i tipi delle classi personalizzate utilizzate nei valori di ritorno dei DataMembers e lo stesso per quelli sotto gerarchia, in pratica tutto ciò che non è un tipo nativo è contrassegnato con [KnownType] in il DataContract. Il problema persiste ancora. –

+0

@LordofScripts puoi creare un progetto di esempio e caricarlo da qualche parte così io (e altri) posso dare un'occhiata. – Phill

+0

Questo è l'ISampleService.cs –

0

Il servizio funziona se si crea un client di prova (come un'app console) e si aggiunge un riferimento al servizio wcf? In tal caso, il tuo datacontract probabilmente ha uno di quei tipi non supportati dal client di test WCF.

See this related issue

+0

L'URL che vedo in quel problema correlato è del tipo .../Name.svc mentre il Client Test WCF mi mostra il seguente URL: http: // localhost: 8731/Design_Time_Addresses/My.WebServices/RegistrationService/mex Se lo uso su IE non mostra nulla. –

0

L'aspettativa di default WCF per una chiamata di servizio è richiesta-risposta - WCF si aspetta una sorta di risposta indietro.

Se si desidera utilizzare void (come in: nessun valore di ritorno), che serve per decorare i metodi con

[OperationContract(IsOneWay = true)] 
void DoSomething(UserData data); 

a dire il runtime WCF non aspettarsi alcun valore di ritorno dalla chiamata

Maggiori informazioni su WCF: Working with One-Way Calls, Callbacks and Events qui su MSDN Magazine.

+0

Non ho mai avuto bisogno di 'IsOneWay == true' per i normali binding in un contratto WCF, non è più adatto per il DualBinding dato che il doppio canale può inviare una risposta indipendente al client? – Silvermind

+0

Non è necessario impostare IsOneWay = true e si dovrebbe essere consapevoli che se lo si fa, il client non riceverà alcuna eccezione di errore lanciata dal server poiché non attende la risposta di annullamento che il servizio wcf restituirà per consentire il ritorno delle eccezioni di errore. –

+0

Anche questo non ha fatto nulla, lo stesso problema. Il mio contratto operativo ha un singolo parametro di un tipo che ho definito contrassegnato con DataContract. Quel tipo personalizzato ha diverse proprietà contrassegnate con DataMember, ciascuna di tipo personalizzato (ma piuttosto semplice), tutti questi sottotipi contrassegnati nella loro dichiarazione come DataContract. –

5

OK, dopo aver attraversato il tutto (grazie a tutti per i suggerimenti) la soluzione è stata questa:

  • attributo IsReference in DataContract non era necessario a tutti
  • IsOneWay attributo DataContract non era necessario del tutto anche quando OperationContract stava ritornando vuoto.
  • KnownType non era necessario purché tutti i sottotipi nella gerarchia fossero miei, in altre parole definiti da me piuttosto che.NET e contrassegnato con DataContract o DataMember come appropriato
  • Sbarazzarsi di OperatingSystem e creare un wrapper DataContract che ha estratto le informazioni necessarie da OperatingSystem ha risolto il problema.

Ora non c'è errore nella prova WCF client

+1

Ciao bloccato con un problema simile. Cosa intendi esattamente per "Eliminare OperatingSystem e creare un wrapper DataContract che ha estratto le informazioni necessarie da OperatingSystem ha risolto il problema." – Neeraj

+0

Bloccato anche su questo, potremmo ottenere un aggiornamento? – Feign