【问题标题】:How to get complex object from controller to view via Ajax get request?如何通过 Ajax 获取请求从控制器获取复杂对象以查看?
【发布时间】:2012-07-05 08:22:35
【问题描述】:

我正在尝试通过 JQuery $.getJSON 将复杂的 ViewModel 对象提取到我的视图中。然而,虽然它适用于简单对象,但当我的视图模型包含其他对象列表作为其中的一部分时,我的 Ajax 请求将停止工作。

这就是我获取数据的方式,

$.getJSON('/Company/GetCompanies', function(data) { 
    viewModel.model = ko.mapping.fromJS(data)
    ko.applyBindings(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类,并填入CompanyIndexviewmodel的FillCompanies()方法,我的ajax get请求停止工作。

这是我的控制器顺便说一句,在这两种情况下它都会返回正确的数据,但是当我添加复杂对象时 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')
});

例如,警报在没有复杂对象时工作,但当我将对象添加到视图模型时它停止工作。


编辑 2

这是我从浏览器而不是 ajax 调用“Company/GetCompanies”时的错误。

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


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

【问题讨论】:

  • 所以您想返回 CompanyWithDetails 和所有相关的 CompanyFaxNumbers? CompanyFaxNumber 是实体吗?它是否有对 Company 或 CompanyWithDetail 的反向引用?
  • 是的,它确实有对公司的外键引用。我更新了我的问题。感谢您的评论。

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


【解决方案1】:

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

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

【讨论】:

  • +1 表示旧的“使用视图模型”,我相信这将是您的墓志铭... ;-)
  • 使用视图模型并停止将您的域模型传递给视图。这句话解决了人们在开发 ASP.NET MVC 应用程序时遇到的 99.99% 的问题。如果只有所有开发人员都可以遵循这个建议,asp.net-mvc 标记在 Stack Overflow 上将是一个孤独的地方 :-) 不幸的是,所有这些 EF 和 CodeFirst 的东西给这些开发人员提供了太多的诱惑,他们很快就掉进了陷阱。
  • 我明白你的意思。我需要查看模型本身的大部分属性。这就是我直接在我的视图模型中使用这些模型的原因。谢谢,以后会避免这种情况。
【解决方案2】:

默认 JSON 序列化程序无法处理循环引用。您可能拥有 Company with Emails 属性,并且每个 Email 都再次引用了 Company。

您需要发送一个视图模型,如 Darin suggested(无论如何这是最佳做法):

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

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

Circular reference exception when serializing LINQ to SQL classes

【讨论】:

    【解决方案3】:

    您可以使用 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 {
    
    
                    }
                }
               });
    

    而你的action方法应该是一个Json结果

    public JsonResult ActionName(perameter)
        {
    
                var modle= getobject();
                return Json(modle);
      }
    

    在上述情况下,您将在 ajax 调用的成功方法中收到结果将与您发送的完全相同的对象...无需序列化或任何技巧..看起来很简单

    【讨论】:

      猜你喜欢
      • 2014-11-14
      • 2017-09-06
      • 1970-01-01
      • 1970-01-01
      • 2018-10-11
      • 1970-01-01
      • 2012-02-11
      • 2014-10-07
      • 2015-01-03
      相关资源
      最近更新 更多