2012-04-12 13 views
5

Mam ServiceContract która zwraca typ dynamiczny i wygląda jak następuje:DataContract i dynamiczny typ zwracany WCF

public dynamic LoginViaOpenId(string openIdUrl) 

Dynamiczny typ zysk może być DataContract że mam określone, lub ciąg. Ale ponieważ nie korzystałem z mojej usługi DataContract, klient nic o niej nie wie i nie ma do niej dostępu.

Moja DataContract jest coś takiego jak poniżej:

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

wiem, czy miałem hierarchicznych typów mogłem użyć KnownType podbić, ale jestem z ideą dla tego scenariusza. Każdy pomysł?

Odpowiedz

16

Dynamiczny DataContract to oksymoron. DataContract jest z góry ustaloną i wspólnie uzgodnioną strukturą danych, a dynamic jest obiektem, którego struktura nie jest z góry określona, ​​a zatem nie może być uzgodniona, ponieważ może być cokolwiek.

Wygląda na to, że nie trzeba zwracać dynamicznego typu danych, lecz zmienny typ danych. Różnica polega na tym, że zmienny typ danych jest jednym ze zbioru stałych typów danych, podczas gdy dynamiczny typ danych to taki, który nie ma z góry określonej struktury. Ponieważ twoja wartość zwracana jest jednym z wielu znanych kształtów, nie ma potrzeby używania dynamicznego typu "shapeless" (lub "freeform"), który nie jest obsługiwany przez WCF.

Zamiast tego można mieć metoda [OperationContract] powrócić typ z [DataContract] która będzie działać jako obiekt otoki, który ma jeden element danych typu object i używać [KnownType] na obiekcie opakowania do określenia możliwych typów, które mogą być wrócił do opakowania. Ponieważ wszystko dziedziczy po object, istnieje już hierarchia.

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

dzięki za elegancki pomysł :-) – CjCoax

3

Myślę, że WCF będzie mieć problemy z serializowaniem/deserializacją twojego dynamicznego typu. Poleciłbym, abyś przygotował kontrakt na zwrócenie metody na podstawie zdefiniowanego interfejsu. Ewentualnie możesz sam wziąć odpowiedzialność za serializację i sprawić, że twoja usługa zwróci ciąg znaków. Klient będzie musiał wiedzieć, jaki typ rozszyfrować ciąg znaków. Jest to podobne pytanie na ten temat tutaj: -

How to return dynamic List from WCF HTTP Service