如何通过Ajax get请求从控制器到视图获取复杂对象?

时间:2012-07-05 08:22:36

标签: .net asp.net-mvc entity-framework jquery

我试图通过JQuery $.getJSON将复杂的ViewModel对象提取到我的视图中。但是,虽然它适用于简单对象,但当我的viewmodel包含其他对象列表时,我的Ajax请求将停止工作。

这是我获取数据的方式,

$.getJSON('/Company/GetCompanies', function(data) { 
    viewModel.model = ko.mapping.fromJS(data)
    ko.applyBindings(viewModel)
});

这是有效的viewmodel,

public class CompanyIndex
{
    public IList<CompanyWithDetail> Companies { get; set; }

    public void FillCompanies()
    {
        UnitOfWork unitOfWork = new UnitOfWork();
        unitOfWork.CompanyRepository.SetProxy(false);
        var CompanyFromDB = unitOfWork.CompanyRepository.GetCompanyWithDetails();

        Companies = new List<CompanyWithDetail>();
        foreach (Company company in CompanyFromDB)
        {
            CompanyWithDetail newCompany = new CompanyWithDetail();
            newCompany.CompanyName = company.CompanyName;
            Companies.Add(newCompany);

        }
        unitOfWork.Dispose();
    }
}

这是CompanWithDetail类,

// For sake of demonstration it only contains name
public class CompanyWithDetail
{
    public string CompanyName { get; set; }
}

这很好用。但是,当我添加

public IList<CompanyFaxNumber> FaxNumber { get; set; }

这个属性到CompanyWithDetail类,并用FillCompanies() viewmodel的CompanyIndex方法填充,我的ajax get请求停止工作。

这是我的控制器btw,在这两种情况下它都返回正确的数据,但是当我添加复杂对象时,jquery $.getJSON没有收到。

public ActionResult GetCompanies()
{
    var model = new CompanyIndex();
    model.FillCompanies();
    return Json(model ,JsonRequestBehavior.AllowGet);   
}

编辑1:

通过说getJSON没有收到数据,我的意思是没有执行函数体。

$.getJSON('/Company/GetCompanies', function(data) { 
    alert('test')
});

例如,当没有复杂对象时警报正在工作,但是当我向viewmodel添加对象时它停止工作。


编辑2

当我从浏览器而不是ajax调用'Company / GetCompanies'时,这是错误。

  

在序列化“CompanyManagement.Models.CompanyEmail”类型的对象时检测到循环引用。


我是否需要做一些特别的事情来将复杂的对象从控制器传递到视图?有什么想法吗?

3 个答案:

答案 0 :(得分:4)

  

我是否需要做一些特别的事情来将复杂的对象从控制器传递到视图?

是的,你应该使用视图模型。您不能JSON序列化对象层次结构,这些对象层次结构包含它们之间的循环引用。如果您希望JSON序列化模型并通过网络发送,则必须打破这些循环引用。 JSON序列化格式根本不支持此。

答案 1 :(得分:1)

默认JSON序列化程序无法处理循环引用。您可能拥有公司电子邮件属性,每封电子邮件都会再次引用公司。

您需要发送一个视图模型,如Darin suggested(这是最好的做法):

http://blog.davebouwman.com/2011/12/08/handling-circular-references-asp-net-mvc-json-serialization/

...或者您可以replace default使用类似Json.NET的JSON序列化程序来处理循环引用:

Circular reference exception when serializing LINQ to SQL classes

答案 2 :(得分:0)

您可以使用dataType = json

简单地进行ajax后调用
    $.ajax({
                type: 'POST',
                url: '@Url.Action("actionName", "controllerName")',
            data: JSON.stringify({ *Perameter If Any* }),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (result) {                  
                  if (result != null) {

                } else {


                }
            }
           });

你的动作方法应该是Json结果

public JsonResult ActionName(perameter)
    {

            var modle= getobject();
            return Json(modle);
  }

在上面的案例值中,您将获得ajax调用的成功方法,结果将是您发送的完全相同的对象...无需序列化或任何技巧..简单,因为它看起来