处理对象图 - Web API

时间:2012-06-20 20:35:16

标签: c# .net json asp.net-web-api

我最近在使用Web API项目时遇到了一个(希望)小问题,该项目涉及返回对象图,以便它们可以作为JSON读取。

任务对象示例 (通过EF生成)

//A Task Object (Parent) can consist of many Activities (Child Objects)
public partial class Task
{
    public Task()
    {
        this.Activities = new HashSet<Activity>();
    }

    public int TaskId { get; set; }
    public string TaskSummary { get; set; }
    public string TaskDetail { get; set; }

    public virtual ICollection<Activity> Activities { get; set; }
}
在我的ApiController中,我被要求一个特定的任务(通过Id)以及所有相关的活动,通过:

单一任务请求示例

//Simple example of pulling an object along with the associated activities.
return repository.Single(t => t.Id == id).Include("Activities");  

一切似乎都运行正常 - 但是当我尝试导航到URL来访问它时,例如/api/tasks/1,该方法按原样执行,但没有返回任何对象(只是一个简单的找不到页)。

如果我请求一个不包含任何活动的任务 - 一切都按预期工作,并返回Activities : []的正确JSON对象。

我确信有很多方法可以解决这个问题 - 我只是想我会对人们认为最好的处理方法有所了解。

考虑的方法(到目前为止):

  • 使用替代的JSON Parser(例如Newtonsoft.JSON)修复了这个问题,但在返回数据中附加了$ id和$ refs,这可能会让解析Knockout变得困难我相信。

  • 使用投影和利用匿名类型返回数据。 (到目前为止未经测试)

  • 完全删除Include,只需通过其他请求访问子数据。

非常感谢任何和所有建议。

1 个答案:

答案 0 :(得分:3)

我最近遇到了与EF类型和Web API类似的问题。根据生成的EF模型的设置方式,导航属性可能会导致循环依赖。因此,如果您生成的Activity类具有Task引用,则序列化程序将尝试遍历对象图并在一个令人讨厌的循环中抛出。

一种解决方案是创建一个简单的视图模型以使序列化器工作

public class TaskViewModel {
  public TaskViewModel ()
  {
     this.Activities = new List<ActivityViewModel>();
   }

  public int TaskId { get; set; }
  public string TaskSummary { get; set; }
  public string TaskDetail { get; set; }

  public virtual IList<ActivityViewModel> Activities { get; set; }
}

public class ActivityViewModel{
  public ActivityViewModel()
  {        
  }

  //Activity stuff goes here
  //No reference to Tasks here!!
}

根据您正在做的事情,您甚至可以创建比这更平坦的模型,但删除任务参考将有助于序列化。这可能就是为什么它在活动为空时起作用