我在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。