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

JSTree无法从JSON数组正常加载,单字符串返回正常数组模式失效

问题:jstree将C#返回的数组解析为纯文本节点

我尝试解决该问题多日但未果:

  • 返回单个JSON字符串时,jstree能正常渲染节点
  • 但将节点添加到List/数组返回时,jstree把每个JSON字符串当作纯文本显示,无法解析字段

弹窗验证的数据格式看似正确,但实际渲染后每个节点都是纯文本JSON字符串(浏览器元素检查结果可见)。


错误核心原因

  1. C#端返回的是字符串数组而非对象数组:手动拼接的JSON字符串存入数组后,WebMethod序列化结果是["{...}","{...}"],前端拿到的是字符串集合,jstree直接把每个字符串当作节点文本,不会解析为JSON对象。
  2. 前端未正确传递节点数据:原JS代码的success函数仅alert结果,未将处理后的对象数组返回给jstree。
  3. SQL存在注入风险:原代码直接拼接SQL参数,属于不安全写法。

修复方案

步骤1:C#端改用实体类返回对象数组

不再手动拼接JSON,创建节点实体类让WebMethod自动序列化:

1.1 定义节点实体类

public class JsTreeNode
{
    public string id { get; set; }
    public string parent { get; set; }
    public string text { get; set; }
    public string type { get; set; }
    public string value { get; set; }
}

1.2 修改WebMethod代码

[WebMethod]
public static List<JsTreeNode> getChildren(string libraryID)
{
    List<JsTreeNode> documentList = new List<JsTreeNode>();
    // 使用using自动释放数据库资源
    using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
    {
        con.Open();

        // 获取根节点名称(参数化查询防注入)
        string getUserInfo = "select LibraryName from Document_Library_Names where Id = @LibraryID";
        SqlCommand getUserInfocmd = new SqlCommand(getUserInfo, con);
        getUserInfocmd.Parameters.AddWithValue("@LibraryID", libraryID);
        string libraryName = Convert.ToString(getUserInfocmd.ExecuteScalar()).Trim();

        // 添加根节点对象
        documentList.Add(new JsTreeNode
        {
            id = libraryName,
            parent = "#",
            text = libraryName,
            type = "FDR",
            value = "0"
        });

        // 获取文档列表(参数化查询)
        string strGetDocuments = "Select * from Documents where LID = @LibraryID order by DisplayOrder ASC";
        SqlCommand getDocumentsCMD = new SqlCommand(strGetDocuments, con);
        getDocumentsCMD.Parameters.AddWithValue("@LibraryID", libraryID);

        DataTable dt = new DataTable();
        using(SqlDataReader sqlDR = getDocumentsCMD.ExecuteReader())
        {
            dt.Load(sqlDR);
        }

        if(dt.Rows.Count > 0)
        {
            foreach(DataRow row in dt.Rows)
            {
                string ID = row[0].ToString().Trim();
                string name = row[3].ToString().Trim();
                string parentFolder = row[4].ToString().Trim();
                string displayOrder = row[5].ToString().Trim();
                string extension = row[8].ToString().Trim();

                string parentFolderID = libraryName; // 默认父节点为根
                if(!string.IsNullOrEmpty(parentFolder))
                {
                    // 查询父文件夹ID(参数化查询)
                    string strParentFolderID = "Select ID from Documents where Name=@Name and Type=0";
                    using(SqlCommand strParentFolderIDcmd = new SqlCommand(strParentFolderID, con))
                    {
                        strParentFolderIDcmd.Parameters.AddWithValue("@Name", parentFolder);
                        object result = strParentFolderIDcmd.ExecuteScalar();
                        if(result != null)
                        {
                            parentFolderID = result.ToString();
                        }
                    }
                }

                // 添加子节点对象
                documentList.Add(new JsTreeNode
                {
                    id = ID,
                    parent = parentFolderID,
                    text = name,
                    type = extension,
                    value = displayOrder
                });
            }
        }
    }
    return documentList;
}

步骤2:修改前端JS代码,正确传递节点数据

调整jstree的data配置,确保将WebMethod返回的对象数组传给jstree:

<script src="Scripts/jquery-3.6.1.js"></script>
<script src="Scripts/jstree.js"></script>
<link href="Scripts/themes/default/style.css" rel="stylesheet" />
<div id="libraryTreeview"></div>

<script type="text/javascript">
    const queryString = window.location.search;
    const urlParams = new URLSearchParams(queryString);
    const libraryID = urlParams.get('ID');

    $('#libraryTreeview').jstree({
        "core": {
            "data": function (node, cb) {
                $.ajax({
                    type: "POST",
                    url: "LibraryFiles.aspx/getChildren",
                    data: JSON.stringify({ libraryID: libraryID }),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (results) {
                        // 将返回的对象数组传给jstree
                        cb(results.d);
                    }
                });
            },
            "themes": {
                dots: false,
                "variant": "large",
                "responsive": true
            }
        }
    });
</script>

修复后说明

  • C#端返回的是List<JsTreeNode>,WebMethod会自动序列化为JSON对象数组[{"id":"...",...}, {...}]
  • 前端拿到对象数组后,jstree可以正确识别每个节点的id、parent、text等属性,渲染出正常的树形结构
  • 同时修复了SQL注入风险,代码更安全可靠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:55:19