You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在ASP.NET Core 2.2中通过Ajax获取子模型数据的问题

解决ASP.NET Core 2.2 Ajax返回JSON值为undefined的问题

我来帮你快速定位并解决这个问题——你遇到的Ajax返回undefined的情况,大概率是后端序列化配置、实体类属性定义,或者前端上下文的问题,咱们一步步排查修复:

1. 先排查请求本身是否正常

首先打开浏览器开发者工具(按F12),切换到Network标签页,触发展开菜单的操作,找到SubMenu的请求:

  • 如果请求状态码不是200:检查url: "/User/SubMenu"是否正确(确保你的控制器是UserController,且SubMenu方法标记了[HttpGet],虽然默认允许GET,但显式标记更稳妥);另外确认pid参数是否正确传递。
  • 如果状态码是200但返回内容为空/格式错误:问题出在后端的Json序列化环节。

2. 修复后端序列化问题

最可能的原因:实体类属性没有公共getter

先检查AuthDepartment类的属性定义,确保DepartId、DepatName、NavUrl这些字段是公共且带有get访问器的,比如:

public class AuthDepartment
{
    public int DepartId { get; set; }
    public string DepatName { get; set; } //注意你这里拼写是DepatName,前端要和这个一致
    public string NavUrl { get; set; }
    public int ParentMenuId { get; set; }
    //其他属性...
}

如果属性是私有或者没有getter,Json序列化器会直接忽略它们,导致返回空数组或者无效的JSON结构。

简化控制器返回逻辑,避免中间对象干扰

你当前的控制器代码是把查询结果赋值给subcomp._InstanceDepartment再返回,这个中间对象UserSecurityMains的_InstanceDepartment如果是私有字段(下划线开头通常是私有命名约定),序列化器也会忽略它。直接返回查询到的列表更稳妥:

[HttpGet] //显式标记为GET请求
public JsonResult SubMenu(string pid)
{
    System.Threading.Thread.Sleep(1000);
    int pID = 0;
    int.TryParse(pid, out pID);
    using (QAEntities context = new QAEntities())
    {
        var subDepartments = context.AuthDepartment
            .Where(x => x.ParentMenuId.Equals(pID))
            .OrderBy(c => c.DepatName)
            .ToList();
        //直接返回列表,跳过中间对象
        return Json(subDepartments);
    }
}

处理可能的循环引用问题

如果AuthDepartment类有导航属性(比如关联父部门的属性),可能会触发循环引用,导致序列化失败。可以在Startup.cs中配置Json序列化忽略循环引用:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddJsonOptions(options =>
        {
            options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        });
}

3. 修复前端Ajax的上下文和错误处理

确保this1的上下文正确

在Ajax的success回调中,this的上下文会发生变化,如果你之前的this1是点击的元素,一定要在请求前保存它的引用,避免DOM操作失效:

// 假设点击事件是绑定在.collapsible上的
$('.collapsible').click(function() {
    var $currentElement = $(this); // 保存当前点击元素的引用
    var pid = $currentElement.attr('pid');

    $.ajax({
        url: "/User/SubMenu",
        type: "GET",
        data: { pid: pid }, // 明确传递pid参数
        dataType: "json",
        beforeSend: function() {
            $currentElement.addClass("loadingP");
        },
        success: function (d) {
            $currentElement.removeClass("loadingP");
            console.log(d); // 先在控制台打印d,确认是否有数据
            if (d && d.length > 0) {
                var $ul = $("<ul></ul>");
                $.each(d, function (i, ele) {
                    $ul.append(
                        $("<li></li>").append(
                            `<span class='collapse collapsible' data-loaded='false' pid='${ele.DepartId}'>&nbsp;</span>` +
                            `<span><a href='${ele.NavUrl}'>${ele.DepatName}</a></span>`
                        )
                    );
                });
                $currentElement.parent().append($ul);
                $currentElement.addClass('collapse').toggleClass('collapse expand');
                $currentElement.closest('li').children('ul').slideDown();
            } else {
                // 处理无数据的情况
            }
        },
        error: function(xhr, status, error) {
            console.error("请求出错:", status, error); // 打印错误信息,快速排查问题
            $currentElement.removeClass("loadingP");
        }
    });
});

增加error回调能帮你快速发现请求失败的原因,比如参数错误、路径错误等。

4. 最后验证数据传递

在控制器的SubMenu方法里设置断点,查看pid的值是否正确,以及查询到的subDepartments是否有数据——如果后端能查到数据,那按照上面的步骤调整后,前端应该能正常获取到JSON数据了。

内容的提问来源于stack exchange,提问作者PatsonLeaner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:54:52