我在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团队(这是我最后一次使用后端B.T.W)暴露了参考循环处理:(WebApiConfig.cs)
JsonMediaTypeFormatter jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
var jSettings = new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
};
jsonFormatter.SerializerSettings = jSettings;
那说它不起作用。
也不是“MaxDepth”属性。
我已经搜索了很多方法,并且找不到实现这一点的内置方法(有很多“黑客”)可以实现JsonConverter(以及[JsonIgnore])的一些变化,这些变化有助于实现这一点。
这是控制响应深度的非常常见请求,不是吗?
微软完全无视这个问题的任何机会,并没有内置的方法来处理这个问题????
答案 0 :(得分:2)
我认为根本问题是你的API试图在一次通话中做太多。我可能会将其拆分为/api/categories
,/api/categories/{id}
,/api/category/{id}/items
,/api/items/{id
}。第一个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。