WebAPI 序列化深度和循环引用



我在WebApi Restful服务上返回了一些组合对象(为简单起见):

class Item {
    List<Category> Categories { get; set; }
    object Value { get; set; }
}
class Category {
    List<Item> ItemsInCategory { get; set; }
}

这些值由一个简单的 ApiController 提供:

 publicHttpResponseMessage getItems()
 {
     List<Category> categories;
     ...
     return Request.CreateResponse(HttpStatusCode.OK, new { results = items});
 }

问题:假设项目(A)在类别(A)中,这将导致循环依赖关系,这将"卡住"序列化。因此,webapi团队(这是我最后一次用作后端BTW)公开了引用循环处理:(WebApiConfig.cs)

JsonMediaTypeFormatter jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
var jSettings = new JsonSerializerSettings()
     {
        Formatting = Formatting.Indented,
        DateTimeZoneHandling = DateTimeZoneHandling.Utc,
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
     };
jsonFormatter.SerializerSettings = jSettings;

也就是说,它并没有真正起作用。也不是"最大深度"属性。
我已经搜索了很多方法,但找不到一种内置的方式来实现这一目标(有许多"黑客攻击"),这些方法可以实现 JsonConverter 的一些变体(以及 [JsonIgnore]),这有助于实现一定比例的这一点。
这是一个非常常见的请求,用于控制响应的深度,不是吗?
Microsoft完全忽略了这个问题,并且没有内置的方法来解决这个问题????

我认为

根本问题是您的 API 试图在一次调用中做太多事情。 我可能会把它分成/api/categories/api/categories/{id}/api/category/{id}/items/api/items/{id}。 第一个 url 将仅返回类别信息,第二个详细信息将返回有关类别的信息,第三个信息将返回有关该类别中的项目的信息,第四个 url 将返回有关项目的详细信息。 您将在 API 中扁平化模型,以便不表示递归数据,而是在获取项目的详细信息时包含 URL 以检索项目所属类别的信息。

例如,/api/items/foo将返回如下内容:

{
    "name" : "foo",
    "value" : "bar",
    "categories" [
       {
           "name" : "Cat A",
           "parent" : {
               "name" : "Top Cat A",
               "location" : "/api/categories/topcata"
           }
           "location" : "/api/categories/cata"
       },
       {
           "name" : "Cat B",
           "parent" : null,
           "location" : "/api/categories/catb"
       }
    ]
}

这会将序列化问题转变为模型映射问题,您可以对其进行更多控制。我认为它还为您的消费者提供了一个更干净、更易于管理的 API。

相关内容

  • 没有找到相关文章

最新更新