1

我有一些POCO對象設置爲與Entity Framework Code First一起使用。如何從ApiController反序列化數據

我想從我的ASP.NET MVC 4網站的ApiController中返回其中一個對象,然後在客戶端應用程序中使用它。

我最初在服務器端的對象序列化時遇到問題,因爲實體框架正在妨礙(請參閱Can an ApiController return an object with a collection of other objects?),它試圖序列化EF代理對象而不是普通的POCO對象。所以,我在我的DbContext中關閉了代理生成,以避免這種情況 - 現在我的序列化對象看起來很好(在我眼中)。

有問題的對象是「標籤」 - 這裏是我的POCO類:

public class Tag 
{ 
    public int Id { get; set; } 

    public int ClientId { get; set; } 
    public virtual Client Client { get; set; } 

    [Required] 
    public string Name { get; set; } 

    [Required] 
    public bool IsActive { get; set; } 
} 

漂亮的標準的東西,但要注意的客戶端Id和客戶端的成員。這些是EF Code First的「導航」屬性。 (每個標籤只屬於一個客戶端)。

這是我從我的ApiController得到:

<Tag xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Foo"> 
    <Client i:nil="true"/> 
    <ClientId>1</ClientId> 
    <Id>1</Id> 
    <IsActive>true</IsActive> 
    <Name>Example</Name> 
</Tag> 

客戶成員是零,因爲有殘疾代理代我沒有得到引用的對象的自動加載。這很好,在這種情況下 - 我不需要客戶端的數據。

所以現在我試圖在客戶端反序列化這些對象。我曾希望能夠在客戶端應用程序中重新使用相同的POCO類,而不是創建新的類。乾和所有這一切。所以,我想:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(Tag)); 

var tag = xmlSerializer.Deserialize(stream); 

但我碰到的兩個問題,這兩個對EF代碼優先約定是由於:

問題1:因爲我的標籤類有一個客戶端成員,XmlSerializer抱怨說它不知道如何反序列化。我認爲這很公平(儘管我希望這是因爲該成員在XML中爲零,所以不會在意)。我可以在XmlSerializer構造函數中傳入額外的類型,當我嘗試時,它會抱怨客戶端使用的其他類。由於客戶端引用各種其他對象,我最終不得不將它們全部傳入!

我嘗試使用[DataContract]和[DataMember]屬性從XML中刪除客戶端成員(通過將其標記爲DataMember)。這確實從XML中移除了它,但並沒有停止XmlSerializer的抱怨。所以我猜這不是事實,它在XML中是問題,而是它在類定義中。

問題2:當我嘗試傳入typeof(Client)作爲額外類型時,它也抱怨說它不能反序列化該類,因爲它包含一個接口成員。這是因爲 - 再次由於EF代碼優先約定 - 它有一個標籤成員如下:

`public virtual ICollection<Tag> Tags { get; set; }` 

所以看起來就算我得到了引用類型的問題,我還沒有打算能使用我的POCO課程。

是否有解決方案,或者我必須創建新的DTO類純粹是爲了在客戶端使用,並返回從我的ApiController?

回答

0

我剛剛嘗試使用DataContractSerializer而不是XmlSerializer,並且對於似乎可以工作的Tag類。我還沒有試過它與虛擬ICollection<T>成員的類...

更新:試過了,它「工作」。它仍然設法重建對象,並將ICollection成員保留爲空。

更新2:好的,那竟然是一個死衚衕。是的,這意味着我可以正確地序列化和反序列化類,但正如大家一直告訴我的那樣,DTO類是更好的方法。 (DTO =數據傳輸對象 - 專門爲在線路上傳輸數據而創建的類,可能包含原始字段的一個子集)。

現在,我使用AutoMapper(感謝的Cuong LE),這樣我可以輕鬆地將我的POCO實體成更簡單的DTO類系列化,而這正是我建議,當面對同樣的問題的人。

+0

不客氣:) – 2012-08-03 14:27:33