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

ASP.NET Core 6 MVC中View调用Controller返回JSON数据解析问题

ASP.NET Core 6 接口返回JSON及前端解析问题解决方案

问题描述

在ASP.NET Core 6控制器中编写接口后,视图通过AJAX调用能收到响应,但无法正确解析返回数据;此前依赖的JsonRequestBehavior.AllowGet在.NET 6中已被弃用,需要一个能返回任意动态对象的更优JSON方案,当前响应数据显示为undefined。

原控制器代码

public IActionResult GetAccountLevelAndCode(Int32 GroupAccountID, Int32 Companyid)
{
    string AccountLevels = ""; string Returnerror; string ReturnBranches;
    DataTable AL = new GetDataClass().GetAccountNoAndAndLevels(GroupAccountID, Companyid, out Returnerror);
    //a = (GLChartOFAccountModel)AL.Rows[0].ConvertDataRowToObject(a);
    string Sql = @"select cab.BranchID from GLChartOFAccount ca inner join GLChartOfAccountBranchDetail cab on ca.GLCAID=cab.GLCAID where cab.GLCAID=" + GroupAccountID;

    DataTable dt = new DataTable();
    dt = StaticClass.SelectAll(Sql).Tables[0];

    AccountLevels = JsonConvert.SerializeObject(AL);
    ReturnBranches = JsonConvert.SerializeObject(dt);

    Returnerror = JsonConvert.SerializeObject(Returnerror);

    return Json(new { AccountLevels, ReturnBranches, Returnerror });
}

原视图AJAX调用代码

function GetAccountNoandLevel() {
    var DATA={"GroupAccountID" : $('#isParent').val(), Companyid : @Model.CompanyID }
    var execCode = true;
    $.ajax({
        async: false,
        type: "POST",
        url: "/GLChartOFAccount/GetAccountLevelAndCode",
        data: DATA,
        dataType: "json",
        success: function (data) {
            try {
                var c = JSON.parse(data.AccountLevels)
                var b = JSON.parse(data.ReturnBranches)
                var er = JSON.parse(data.Returnerror)

                if (b.length>0) {

                    $("#BrachIDs option").each(function () {
                        var idParent = $(this).parent().attr("id");
                        this.disabled = true;
                    });
                    var dataarray = '';
                    for (var i = 0; i < b.length; i++) {
                        dataarray += b[i]["BranchID"] + ',';
                    }
                    dataarray = dataarray.replace(/,\s*$/, "");
                    var data = dataarray.split(",");
                    $("#BrachIDs").val(data);
                    $("#BrachIDs").change();
                    if (data.length > 0) {
                        for (var i = 0; i < data.length; i++) {
                            $("#BrachIDs option").filter("[value='" + data[i] + "']").attr('disabled', false);
                        }
                    }
                }
                else {
                    $("#BrachIDs option").each(function () {
                        var idParent = $(this).parent().attr("id");
                        this.disabled = false;
                    });
                    $("#BrachIDs option:selected").removeAttr("selected");
                }

                if (ShowErrorOK(er)) {
                    $('#GLCode').val('');
                }else{
                    RowToFillValues(c)
                }

            } catch (e) {
                //console.log(e + " GetAccountNoandLevel "); document.getElementById("DisplayErrorMessage").innerText = e.message; $('#btnTriggerMessage').click(); execCode = false; return false;
                console.log(e + " GetAccountNoandLevel "); console.log(e.message)
            }
        },
        error: function (err) {
            //console.log(err.responseText); document.getElementById("DisplayErrorMessage").innerText = "AJAX error in request: " + JSON.stringify(err.statusText + " " + err.status) + " GetAccountNoandLevel::Unable To Get Details"; $('#btnTriggerMessage').click(); execCode = false; return false;
            console.log("AJAX error in request: " + JSON.stringify(err.statusText + " " + err.status) + " GetAccountNoandLevel::Unable To Get Details")
        }
    });

    if (execCode) {
        
    }
}

问题根源及优化方案

1. 控制器核心问题:双重序列化导致解析异常

原控制器中手动用JsonConvert.SerializeObject序列化DataTable和字符串,再通过Json()方法返回,相当于做了双重JSON序列化——前端拿到的是被转义后的字符串,而非直接可用的JSON对象,这会导致JSON.parse失败或解析出异常数据,最终出现undefined。

另外,.NET 6中Json()方法默认已允许GET/POST请求返回JSON,无需再使用已弃用的JsonRequestBehavior.AllowGet。

2. 优化后的控制器代码

直接返回包含DataTable和错误信息的匿名对象,由ASP.NET Core框架自动完成序列化:

public IActionResult GetAccountLevelAndCode(Int32 GroupAccountID, Int32 Companyid)
{
    string returnError;
    DataTable accountLevels = new GetDataClass().GetAccountNoAndAndLevels(GroupAccountID, Companyid, out returnError);
    
    // 必须使用参数化查询避免SQL注入风险
    string sql = @"select cab.BranchID from GLChartOFAccount ca 
                   inner join GLChartOfAccountBranchDetail cab on ca.GLCAID=cab.GLCAID 
                   where cab.GLCAID = @GroupAccountID";
    // 假设StaticClass.SelectAll支持传入参数对象,若不支持需改用SqlCommand添加参数
    DataTable branches = StaticClass.SelectAll(sql, new { GroupAccountID }).Tables[0];

    return Json(new { AccountLevels = accountLevels, ReturnBranches = branches, ReturnError = returnError });
}

3. 优化后的前端AJAX代码

控制器返回的是直接可用的JSON对象,无需再调用JSON.parse,直接访问属性即可:

function GetAccountNoandLevel() {
    var DATA = {"GroupAccountID" : $('#isParent').val(), Companyid : @Model.CompanyID };
    var execCode = true;
    $.ajax({
        async: false,
        type: "POST",
        url: "/GLChartOFAccount/GetAccountLevelAndCode",
        data: DATA,
        dataType: "json",
        success: function (response) {
            try {
                const accountLevels = response.AccountLevels;
                const branches = response.ReturnBranches;
                const returnError = response.ReturnError;

                if (branches.length > 0) {
                    $("#BrachIDs option").prop('disabled', true);
                    const branchIds = branches.map(item => item.BranchID);
                    $("#BrachIDs").val(branchIds).change();
                    branchIds.forEach(id => {
                        $("#BrachIDs option[value='" + id + "']").prop('disabled', false);
                    });
                } else {
                    $("#BrachIDs option").prop('disabled', false).removeAttr('selected');
                }

                if (ShowErrorOK(returnError)) {
                    $('#GLCode').val('');
                } else {
                    RowToFillValues(accountLevels);
                }
            } catch (e) {
                console.log("GetAccountNoandLevel 异常:", e);
                console.log("异常信息:", e.message);
            }
        },
        error: function (err) {
            console.log("AJAX请求错误:", `状态: ${err.status} ${err.statusText}`, "GetAccountNoandLevel::无法获取详情");
        }
    });

    if (execCode) {
        // 后续逻辑
    }
}

优化说明:用prop替代attr操作表单元素属性(符合jQuery最佳实践),用map简化数组转换,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:15:35