从MVC控制器返回包含对象列表的JsonResult

19

我在我的MVC控制器中有一个简单的方法:

[HttpPost]
public JsonResult GetAreasForCompany(int companyId)
{
   var areas = context.Areas.Where(x => x.Company.CompanyId == companyId).ToList();
   return Json(areas);
}

这是一个区域对象:

public class Area
{
    public int AreaId { get; set; }

    [Required]
    public string Title { get; set; }
    public bool Archive { get; set; }

    public virtual Company Company { get; set; }
}

我是如何从视图中调用该方法的:

$.ajax({
    url: '@Url.Action("GetAreasForCompany")',
    type: 'POST',
    async: false,
    data: "{'companyId': " + companyId + "}",
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    error: function () {
        alert("Server access failure!");
    },
    success: function (result) {
        response = result;
    }
});

我已经检查了控制器中的方法,并创建了一个Area对象列表。您有任何想法为什么从视图调用该方法时会出现500内部服务器错误?当我返回其他东西时(比如词典对象),一切都正常,只有当我试图将Area对象列表转换为Json时才会出错。


2
Company 是否包含一个 Area 集合? - user3559349
是的,公司有区域集合。 - Bartosz
1
好的,很可能是循环引用问题。你实际上需要在结果中返回 Area 的哪些属性? - user3559349
标题和区域ID。我应该创建一个仅包含这两个属性的匿名对象吗? - Bartosz
1
准确地说 - .Select(a => new .... (它还有减少有效载荷的好处) - user3559349
那是一个答案。如果您将其格式化为适当的答案,我可以将其标记为问题的答案。 - Bartosz
2个回答

25

由于类Area包含Company,而Company又包含Area的集合,因此您的对象层次结构中可能存在循环引用,这是JSON序列化器不支持的。为了解决这个问题,您可以返回只包含所需属性的匿名对象,例如:

[HttpPost]
public JsonResult GetAreasForCompany(int companyId)
{
  var areas = context.Areas
    .Where(x => x.Company.CompanyId == companyId)
    .Select(a => new
    {
      AreaId = a.AreaId,
      Title = a.Title
    });
  return Json(areas);
}

抱歉问一个不相关的问题,这里为什么要使用 HttpPost 而不是 HttpGet - Aaron Campbell
3
@AaronCampbell,没有任何理由需要使用 [HttpPost],因为它不会更改任何数据 - 也可以使用 [HttpGet](除非您不希望将URL添加到浏览器历史记录中)。只是使用了OP所提供的内容 :) - user3559349

5

将列表对象作为Json返回(对于JqueryUI和Linq方法也很有用)

public ActionResult GetItemList()
{
    var search = Request.Params["term"];

    var itemList = (from items in db.TblItems where items.ItemName.StartsWith(search) select new { label = items.ItemName, value = items.ItemName }).ToList();

    return Json(itemList, JsonRequestBehavior.AllowGet);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接