12

假设我有这些具有这些关系的实体:这只是一个虚构的例子,而不是我当前的实体。

  • 课程
  • 用户
  • 新闻帖子

课程有很多用户,用户有很多课程

Courses 有很多 NewsPosts,NewsPosts 有很多 Courses

用户有很多 NewsPosts,NewsPosts 有很多用户

我首先将实体框架代码与 .NET Web API 一起使用,它以 JSON 的形式发回实体。当我尝试获取课程时,它会返回一个带有实体关系的 JSON 结果,这很好,但我希望设置它序列化的级别的限制,因此它不会序列化第一个之外的所有关系或二级。

GET Course/ 将被序列化为:

   {
     "Users":[{
                "id":1,
                "newsPosts": [{
                                "id":1,
                                "message":"foo"
                             }]
             }],
   "newsPosts":[{
                 "id":2,
                 "message":"bar"
               }]   

   }

我想要的是仅序列化 1 个或 2 个级别,因此结果将是:

   {
     "Users":[{
                "id":1,
                "newsPosts": []
             }],
   "newsPosts":[{
                 "id":2,
                 "message":"bar"
               }]   

   }

我添加了一个:

    json.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

这是为了删除参考循环。

简而言之:有没有办法设置最大数量的节点进行序列化?

4

4 回答 4

1

在我看来,您有两种选择:

  1. 编写自定义序列化程序,或使用现有库(如果可以找到)
  2. 在尝试序列化任何内容之前,准备好您希望端点发回的数据。

涉及 API 的最佳实践之一是只发回所需的数据,因为这会影响发回的数据的大小。

实体框架通过提供太多的方式以某种方式工作,而您想限制它。解决此问题的常用方法是不让 API 返回实体框架实体。原因有很多,可以单独研究。

因此,一种方法是开始使用 DTO 返回数据。这有很多优点:

  1. 您可以控制发回的数据,并且不需要任何自定义序列化程序或另一个库。
  2. 您可以控制响应的内容,这意味着有时您不需要将类中的所有公共属性都发回,您需要一个子集并且您可以控制它。
  3. API 不再与实体框架及其实体紧密耦合。

缺点:

  1. 您现在有另一组类要处理,但是这种复杂性可以通过 AutoMapper 之类的东西轻松管理。
于 2020-10-21T08:11:11.127 回答
-1

我建议使用 AutoMapper 之类的东西将您的域类映射到自定义 DTO 对象,然后将它们传递给序列化。

于 2013-05-02T15:23:17.997 回答
-1

我对 Web API 不是很熟悉,但您似乎想要制作一个使用 JavaScriptSerializer 的自定义 MediaTypeFormatter,它具有设置递归限制的属性。

MSDN - JavaScriptSerializer.RecursionLimit 属性

另一种选择是制作一个使用具有相同选项的 JSON.NET 的自定义格式化程序。

于 2013-05-02T15:38:01.433 回答
-3

这不只是一个关于如何构造从 get 函数发送的数据的问题吗?

我的意思是 JSON 序列化器通过序列化你给他的所有数据来完成它的工作,只需删除数据,或者不包含它,它就不会被序列化。

如果您正在寻找一个自定义的 JsonWriter 是您想要的更好的调整,Alex Filipovici 发布的链接提供了有关如何实现该目标的详细信息。

于 2013-05-02T14:47:14.407 回答