我正在写一个Rest端点,由于某种原因,其余的调用本身仍然返回空内容,即使调试代码显示响应的Content
被定义为我预期的那样。类似的调用也没有表现出同样的问题。最后,我意识到有效的调用和失败的调用之间的区别在于,不成功的调用尝试返回递归(具有该类型的公共属性/字段的类型)或相互递归类型,而成功调用则没有。作为我遇到的问题的最小例子:
[RoutePrefix("")]
public class LoopyController
{
public class Loopy
{
public Loopy Self {get; set;}
}
[HttpGet]
[Route("loopy")]
public HttpResponseMessage LoopyCall()
{
Loopy loopy = new Loopy();
loopy.Self = loopy;
return Request.CreateResponse(loopy)
}
}
GET
端点上的loopy
调用返回空响应。我希望它能挂起或抛出异常。我想知道为什么ASP.Net会出现这种行为。我认识到这个问题的解决方案是修改返回值,使其不再以递归方式呈现,但想知道是否有更简洁的方法来解决此问题。
编辑:
我在评论中讨论了我使用术语“递归类型”的问题。我有信心通过https://en.wikipedia.org/wiki/Recursive_data_type Loopy
是递归类型。 然而,问题不在于类型Loopy
是递归的,而是对象loopy
具有循环引用。以下终点:
[HttpGet]
[Route("notsoloopy")]
public HttpResponseMessage NotSoLoopy()
{
Loopy notSoLoopy = new Loopy();
notSoLoopy.Self = null;
return Request.CreateResponse(notSoLoopy);
}
会在回复{}
请求时返回回复GET
。当然,Loopy
递归会使loopy
具有循环引用。
答案 0 :(得分:3)
这是循环参考。 WebAPI json格式化程序默认设置为忽略循环引用。即使您正在使用XML,我也在考虑(但不确定),无论如何都会忽略它。 This article可能会提供一些见解:
Json.net序列化程序( web api中使用的序列化程序)支持忽略全局循环引用 设置。