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