19

I have a simple method in my MVC controller:

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

This is an area object:

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; }
}

And this is how I call the method from the view:

$.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;
    }
});

I have checked the method in the controller and a list of Area objects gets created. Would you have any idea why do I get the 500 internal server error when the method is called from the view? When I return anything else (like a Dictionary object) everything works fine, it's just when I aim to convert the List of Areas into Json I get an error.

6
  • 2
    Does Company happen to contain a collection of Area? Commented Aug 20, 2014 at 10:58
  • Yes, the Company has collection of Area Commented Aug 20, 2014 at 11:01
  • 1
    Ok, its most likely circular reference issue. Which properties of Area do you actually need to return in the result? Commented Aug 20, 2014 at 11:03
  • Title and AreaId. Should I then create anonymous object, with those two properties only? Commented Aug 20, 2014 at 11:04
  • 1
    Exactly - .Select(a => new .... (and it has the benefit of reducing the payload) Commented Aug 20, 2014 at 11:06

2 Answers 2

25

Since class Area contains Company and Company contains collection of Area you likely have circular references in your object hierarchy which is not supported by the JSON serializer. To solve this, return anonymous objects with only those properties you need, for example

[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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Sorry for an unrelated question, but why would you use HttpPost instead of HttpGet here?
@AaronCampbell, No reason you would need to use [HttpPost] since it's not changing any data - could also be [HttpGet] (unless you did not want the url added to the browser history). Just used what OP had :)
5

Return List Object as Json (Also useful for JqueryUI and Linq Method)

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.