2012-07-03 51 views
1

我有一個接口,並在單獨的組件中定義的類,像這樣的工作:無法獲得KnownType與WCF

namespace DataInterfaces 
{ 
    public interface IPerson 
    { 
     string Name { get; set; } 
    } 
} 

namespace DataObjects 
{ 
    [DataContract] 
    [KnownType(typeof(IPerson)) ] 
    public class Person : IPerson 
    { 
     [DataMember] 
     public string Name { get; set; } 
    } 
} 

這是我的服務接口:

public interface ICalculator 
{ 
    [OperationContract] 
    IPerson GetPerson (); 
} 

當我更新我爲我的客戶服務參考,我得到這個在Reference.cs:

public object GetPerson() { 
    return base.Channel.GetPerson(); 

我希望KnownType會給我IPerson,而不是「對象「在這裏。

我也試過[KnownType(typeof(Person)) ],結果相同。我控制了客戶端和服務器,因此我在兩個地方都有DataObjects(定義了Person)和DataInterfaces(定義了IPerson)程序集。有什麼明顯的我失蹤?我認爲KnownType是能夠使用WCF接口的答案。

-----更多信息請----- 我從Person類中刪除的KnownType並添加

[ServiceKnownType(typeof(Person)) ] 

我的服務接口,由Richard的建議。客戶端代理仍然看起來相同,但現在它不會炸燬。但是現在它不會爆炸。然而,客戶端只有一個「對象」,因此它必須在IPerson有用之前將其轉換爲IPerson。

 var person = client.GetPerson (); 
     Console.WriteLine (((IPerson) person).Name); 

回答

0

你需要把上IPerson的KnownType沒有人是這樣的:

[KnownType(typeof(Person))] 
public interface IPerson 
{ 
    string Name { get; set; } 
} 
+0

我希望這不是答案:)因爲這意味着我不能有單獨的DataObjects和DataInterfaces,因爲這使得循環引用。 'Person:IPerson'與''KnownType Person for IPerson' ...我想我會嘗試它,但我得到一個編譯錯誤,說KnownType只能用於類,結構... –

+0

是的,他們需要進入同一個程序集。另外,如果你的基類是一個類而不是一個接口,你可以通過基類[KnownType(MethodName = ...)]上的靜態方法提供已知類型。或者你可以直接向序列化程序提供已知類型,而不是依靠它來通過屬性或靜態方法發現它們。 –

+0

我真的想把這些程序集分開,但我很欣賞替代方案 - 好的食物。 –

1

如果您需要[ServiceKnownType]的服務合同,則IPerson組件不需要人組裝的知識。

[ServiceKnownType(typeof(Person))] 
public interface ICalculator 
{ 
    [OperationContract] 
    IPerson GetPerson (); 
} 

或者,您可以使用KnownType版本constructor that takes a method name。然後,這可以找到已知的類型,比如配置文件

但是,我不明白你爲什麼在你的合同上使用接口。合同是正在傳遞的消息的定義 - 接口在這種情況下如何提供幫助?

+0

對不起,我不明白你的第一個陳述,我會檢查出來。關於接口如何提供幫助的問題,我有一個曾經是SubSonic的數據訪問層,現在它是EntityFramework。爲了預期這種變化,我們已經抽象出了數據訪問層,以便它交付的是接口類型。 (這是不常見的?)因此,當服務使用數據對象時,它具有接口類型,而不是具體。我認爲我明白了,因爲序列化必須有一個具體的工作,KnownType是解決方法。 –

+0

我在我的ServiceContract上添加了[ServiceKnownType(typeof(IPerson))]',我現在在reference.cs中看到了'public DataObjects.Person GetPerson()...'。那更好。我可以把它變成IPerson嗎? –

+0

同意Richard對接口的評論。通常,這個概念很難映射到WCF所基於的XML Web服務的消息傳遞世界。 WSDL,XSD和XML沒有相同的概念。只要您開始使用這些KnownType屬性,就可以很好地排除這些Web服務與非.NET平臺的互操作性。 –

0

繼承的整個想法是,基類沒有專門的類的知識。用專門的類型裝飾數據契約基類(通常在一個共同的dll中定義)似乎破壞了基本的OOD原則?恕我直言,SvcUtil應該爲您做這項工作,並在生成代理時使用已知類型。當svcutil開發出來時,甚至沒有考慮過基本OO。