2012-04-12 16 views
5

Ho un ServiceContract che restituisce tipo dinamico e si presenta come segue:DataContract e dinamico tipo di ritorno WCF

public dynamic LoginViaOpenId(string openIdUrl) 

Il tipo restituito dinamica potrebbe essere un DataContract che ho definito, o una stringa. Ma dal momento che non ho usato il mio DataContract sul servizio, il client non ne sa nulla e non può accedervi.

mio DataContract è qualcosa di simile di seguito:

[DataContract] 
public enum OpenIdStatus 
{ 
     [EnumMember] 
     Authenticated, 
     [EnumMember] 
     Authenticating, 
     [EnumMember] 
     Cancelled, 
     [EnumMember] 
     Failed, 
     [EnumMember] 
     RedirectToLogon 
} 

so se ho avuto tipi gerarchici avrei potuto usare KnownType per conquistare questo, ma sono fuori di idea per questo scenario. Qualche idea?

risposta

16

Un DataContract dinamica è un ossimoro. Un DataContract è una struttura di dati predeterminata e reciprocamente concordata, e dynamic è un oggetto la cui struttura non è predeterminata e quindi non può essere concordata, poiché può essere qualsiasi cosa.

Non sembra che sia effettivamente necessario restituire un tipo di dati dinamico, ma piuttosto un tipo di dati variabile. La differenza è che un tipo di dati variabile è uno di un set di tipi di dati fissi, mentre un tipo di dati dinamico è uno che non ha una struttura predeterminata. Poiché il valore restituito è una delle diverse forme note, non è necessario utilizzare il tipo dinamico "shapeless" (o "freeform"), che non è supportato da WCF.

Invece, si potrebbe avere il metodo [OperationContract] restituire un tipo con un [DataContract] che agirà come un oggetto wrapper che ha un unico membro di dati di tipo object, e utilizzare [KnownType] sul oggetto wrapper per specificare i tipi possibili che possono essere restituito all'interno del wrapper. Dal momento che tutto eredita da object, esiste già una gerarchia.

[DataContract] 
[KnownType(typeof(OpenIdStatus))] 
[KnownType(typeof(string))] 
public class ReturnValue 
{ 
    [DataMember] 
    public object Value { get; set; } 
} 
+0

grazie per l'idea elegante :-) – CjCoax

3

Penso che WCF abbia problemi di serializzazione/deserializzazione del tipo dinamico. Ti consigliamo di impostare un contratto per il ritorno del metodo basato su un'interfaccia definita. In alternativa, potresti prenderti la responsabilità della serializzazione e rendere il tuo servizio restituire una stringa. Il client dovrà avere conoscenza di quale tipo des-serializzare la stringa su. V'è una domanda simile a questo qui: -

How to return dynamic List from WCF HTTP Service