【问题标题】:How do I access data returned from a controller invoked by an ajax call in an MVC View如何访问从 MVC 视图中的 ajax 调用调用的控制器返回的数据
【发布时间】:2020-02-10 07:56:24
【问题描述】:

我有一个带有以下 JavaScript 的 MVC 5 视图,在调用控制器上的操作方法后出现错误:

<script type="text/javascript">
    $('#ddlvendors').change(function () {
                var descHtml = "";
                var vendorId = $(this).val(); 

                $.ajax(
                    {
                        type: "POST",
                        data: { vendorId: vendorId },
                        url: '@Url.Action("PurchaseOrderVendor")',
                        datatype: "json",
                        success: function (aVendorObject) {
                            alert(aVendorObject.Name);
                        },
                        error: function (req, status, error) {
                            alert(error);
                        }
                     });
            });
</script>

控制器动作方法如下:

[HttpPost]
public ActionResult PurchaseOrderVendor( int vendorId)
{
  Vendor aVendor=VendorServices.GetVendor(vendorId);

  return Json(aVendor);
}

返回的vendor对象如下:

 public class VendorViewModel
  {
    public int VendorId { get; set; }
    public string Name { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Description { get; set; }
    public string ContactName { get; set; }
    public string Phone { get; set; }
  }

使用 Visual Studio 2017 调试器,我可以看到供应商数据已在控制器端正确填充。如果我不尝试访问任何成员数据,则 ajax 调用将完成且不会出现错误。但是,当我尝试访问作为 aVendorObject 传入的任何部分(例如 aVendorObject.Name)时,我会收到一个浏览器错误消息“内部服务器错误”。如何在 ajax 调用中修复我的成功处理程序,以便我可以访问从控制器返回的 Vendor 对象的成员?

提前致谢。

【问题讨论】:

  • 在浏览器上按F12 转到network 部分。然后执行ddlVendor.change() 事件。您将看到失败请求的红色文本。单击它,然后导航到Response 选项卡。你会在那里看到实际的错误!
  • 谢谢。使用 F12 揭示了这个问题。这是一个实体框架问题,它使用了延迟加载的默认行为。当我关闭延迟加载时,数据现在按预期通过。我将通过一个示例来回答这个问题,该示例说明我如何在延迟加载设置为关闭的情况下修改实体框架调用。

标签: javascript jquery asp.net-mvc asp.net-ajax


【解决方案1】:

EntityFramework 6 的延迟加载功能在需要时没有可用的供应商对象。我在 VendorServices 类中添加了一行来关闭修复问题的 LazyLoading。下面是我为这个特定的 VendorService 方法关闭 LazyLoading 的方法:

 static public Vendor GetVendor(int aVendorId)
{
  Vendor vendor;
  using (RgmSiteDAL RgmSiteDALCtx = new RgmSiteDAL())
  {
    //** Now setting LazyLoadingEnabled to false.
    RgmSiteDALCtx.Configuration.LazyLoadingEnabled = false;

    vendor = RgmSiteDALCtx.Vendor
                .Where(v => v.VendorId == aVendorId)
               .FirstOrDefault<Vendor>();

  }
    return vendor;
}

我发现如果我包含使用 Vendor 实体定义的任何导航属性,也可以解决该问题,如下所示:

vendor = RgmSiteDALCtx.Vendor
                   .Where(v => v.VendorId == aVendorId)
                   .Include(v => v.PurchaseOrder) //because is in Vendor navigation property
                  .FirstOrDefault<Vendor>();

对于我的情况,我将坚持将 LazyLoadingEnabled 设置为 false 的第一个解决方案。这是因为从我现有的数据库生成我的实体的选项将我的 PurchaseOrder 表设置为我的供应商的导航属性,我认为这是不正确的。当我查询供应商信息时,我的供应商对象不需要来自 PurchaseOrder 实体的任何内容。我将考虑从我的供应商实体中删除 PurchaseOrder 导航属性,因为我认为它是由 Visual Studio 中的从数据库工具中创建实体错误设置的。

【讨论】:

    猜你喜欢
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    相关资源
    最近更新 更多