【问题标题】:How to deserialize data from ApiController如何反序列化来自 ApiController 的数据
【发布时间】:2012-08-02 06:23:17
【问题描述】:

我有一些 POCO 对象设置为与 Entity Framework Code First 一起使用。

我想从我的 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; }
}

相当标准的东西,但请注意 ClientId 和 Client 成员。这些是 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 Code First 约定引起的:

问题 1:因为我的 Tag 类有一个 Client 成员,所以 XmlSerializer 抱怨它不知道如何反序列化它。我想这很公平(尽管我曾希望因为 XML 中的成员是 Nil,所以它不会在意)。我可以在 XmlSerializer 构造函数中传递额外的类型,当我尝试这样做时,它会抱怨 Client 使用的其他类。由于 Client 引用了各种其他对象,我最终不得不将它们全部传入!

我尝试使用 [DataContract] 和 [DataMember] 属性从 XML 中删除客户端成员(通过不将其标记为 DataMember)。这确实将它从 XML 中删除,但并没有阻止 XmlSerializer 抱怨它。所以我想问题不是在 XML 中,而是在类定义中。

问题 2:当我尝试将 typeof(Client) 作为额外类型传入时,它还抱怨它无法反序列化该类,因为它包含一个接口成员。这是因为 - 再次由于 EF Code First 约定 - 它有一个 Tags 成员,如下所示:

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

所以看起来即使我解决了引用类型问题,我仍然无法使用我的 POCO 类。

是否有解决方案,或者我必须创建新的 DTO 类纯粹用于客户端,然后从我的 ApiController 返回这些类?

【问题讨论】:

    标签: serialization asp.net-mvc-4 asp.net-web-api entity-framework-5


    【解决方案1】:

    我刚刚尝试使用DataContractSerializer 而不是XmlSerializer,并且对于似乎有效的Tag 类。我还没有尝试使用具有虚拟ICollection&lt;T&gt; 成员的类...

    更新:试过了,它“有效”。它仍然设法重建对象,并将ICollection 成员保留为空。

    更新 2:好的,结果证明这是一条死胡同。是的,这意味着我可以正确地序列化和反序列化这些类,但正如每个人一直告诉我的那样,DTO 类是一个更好的方法。 (DTO = 数据传输对象 - 专为通过网络传输数据而创建的类,可能带有原始字段的子集)。

    我现在正在使用 AutoMapper(感谢 Cuong Le),以便我可以轻松地将我的 POCO 实体转换为更简单的 DTO 类以进行序列化,这就是我向面临相同问题的任何人推荐的方法问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      • 1970-01-01
      相关资源
      最近更新 更多