【问题标题】:jquery+jstree in .net - webservice responseformat?.net 中的 jquery+jstree - Web 服务响应格式?
【发布时间】:2010-10-19 14:09:39
【问题描述】:

我第一次使用 c#.net 玩 jstree (1.0rc2)+jquery (1.4.2),虽然我已经让它工作了,但有几件事我不明白数据如何由我用来填充树的 Web 服务提供给树(使用 ajax 和 json_data 插件)。我希望有更多使用 jstree 经验的人可以提供一些见解。

jstree 配置如下所示:

 "json_data": {
                "ajax": {
                    "url": "GetTree.asmx/GetChildren",
                    "type": "POST",
                    "contentType": "application/json; charset=utf-8",
                    "dataType": "json",
                    "data": function(n) {
                        var result = "{'id':'" + (n.attr ? n.attr("id").replace("node_", "") : "0") + "'}";
                        return (result);
                    }
                }
            }

GetTree.asmx GetChildren 方法:

   [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Xml )]
    public string GetChildren(string id)
    {
        List<jsTreeNode> jsTree = new List<jsTreeNode>();
        //... (build the tree as needed)

        JavaScriptSerializer serializer = new JavaScriptSerializer();
        return(serializer.Serialize(jsTree)); 
    }

问题 1:所以一切都很好,那么问题出在哪里?问题是“ResponseFormat = ResponseFormat.Xml”。我挣扎了一段时间才能让它工作,因为当它设置为 ResponseFormat.Json 时它不起作用,这正是我所期望的。在这种情况下,Web 服务或 jQuery 在解析 json 响应时不会报告任何错误,但树会呈现为空。

在查看 Web 服务的 HTML 输出时,我看不出两种方式呈现的内容之间没有区别。我希望有人能解释为什么这有效(违反直觉)以及为什么它不适用于 ResponseFormat.Json,如果这表明我可能做错了其他事情。

问题 2:一般是 Web 服务还是 Web 处理程序?

无论如何,使用通用 Web 处理程序 (ashx) 会是一种更有效的方法吗?标准 Web 服务与通用 Web 处理程序所需的开销是否存在显着差异?由于我的目标基本上是准确控制输出的内容(并且在 Web 服务中使用 json 数据格式似乎并没有按照我想要的方式工作)我不确定有什么好处(如果有的话)在这里使用 Web 服务,而不是完全剥离它。另一方面,这现在可以了,所以也许我应该独自离开。

【问题讨论】:

    标签: c# asp.net jquery json jstree


    【解决方案1】:

    看到这个问题有近 600 次浏览并且没有答案,我想我会自己回答(因为我早就想通了)。

    使用ScriptMethod 确实不是与jQuery ajax 通信的正确方式。虽然可以做到,但您会注意到我在上面所做的是返回一个 string,其中包含我使用 JavascriptSerializer. 将自己编码为 JSON 的数据

    但是,使用ScriptMethod 会自动结合旨在与 Microsoft 的 AJAX 框架进行通信的序列化/反序列化。由于序列化一个没有对象包装器的纯字符串通常会产生相同的字符串(无论我返回 XML 还是 JSON 格式),它基本上可以工作,但内部真正发生的是它被序列化两次 .

    所以我至少应该做的是:

    public List&lt;jsTreeNode&gt; GetChildren(string id)

    也就是说,返回类型应该是实际的数据类型,而不是一串序列化的数据。

    但是,这仍然不完全正确,因为 Microsoft 的方法将返回值包装在对象 d 中。我仍然可以在 Javascript 中提取它以获取内部数据。但是如果像 jsTree 这样的东西需要预定义格式的数据,这可能不可行。

    最好的解决方案是不要使用 WebServices,而是使用通用处理程序 (ashx)。 这使您可以完全控制输入和输出的格式和处理。为自己设置一个不错的框架可能需要做一些事情,但是无法跳过您不需要的 WebService 处理部分的挫败感使其非常值得。

    【讨论】:

    • 很高兴看到你解决了这个问题......我有一个类似的问题,很久以前就得出了结论。如果我看到这个,我会帮忙的。
    【解决方案2】:

    对不起,我不同意你的回答,3.5 框架对 Json 序列化和 Web 服务有很好的支持(对于 2.0,你可以使用 Newtonsoft.Json)。请在http://code.zyky.com/jsTreeView/Default.aspxhttp://asp-net-elephant.blogspot.com/2012/01/how-to-use-jstree-in-aspnet-web-forms.html 上查看我的JsTree ASP.NET Web 控件演示,以获取两者的示例。希望这会有所帮助。

    【讨论】:

    • 你的例子看起来很棒! 10 年 10 月,当我还是树林里的宝贝时,你在哪里? :) 事后看来,尽管如此,我绝对不会建议有人使用 Web 服务开始一个新项目。现在有更好的东西,比如 WCF,或者使用 System.Web.Routing 并推出你自己的 REST 框架,例如blogs.msdn.com/b/henrikn/archive/2012/02/23/…
    【解决方案3】:

    关于问题 1(我无法与 Q2 交谈),我已经获得了一个 Web 服务来将 JSON 反馈给 jsTree 插件。虽然我认识到 WCF 和 REST 是更现代的方法,而且从长远来看无疑会更好,但我们仍然使用 asmx Web 服务,它们确实完成了工作。但这并不容易:我花了一段时间试图获得在 JS 中工作的确切语法,以便 jsTree 可以从 ASP.NET Web 服务中获取其数据对象。正如 OP 在他的解决方案中所暗示的那样,问题不在于我的 JS 和插件的接线,而在于我的 Web 服务返回的不稳定的 JSON 数据。它看起来像 JSON,但它是简化 JSON 对象的字符串表示。

    为了修复它,我必须反序列化和序列化我的 json 字符串(我从 https://stackoverflow.com/a/20080495/1129926 得到了一个线索),结果对象被 jsTree 愉快地使用了。这是我的网络服务:

    Imports System.Web.Script.Serialization
    
    Public Function GetJsonData() As String
        Dim jss As JavaScriptSerializer = New JavaScriptSerializer
        ' IMPORTANT: do not use single quotes ' in JSON string, use ""
        Dim jsonData As String = "" & _
        "{ ""text"": ""CONTACTS"", ""children"": [ { ""text"": ""CUSTOMER"", ""column"": ""CLASS"", ""children"": [ { ""text"": ""Excelo Communications"", ""column"": ""COMPANY"", ""children"": [{ ""text"": ""Fred Shorts"", ""column"": ""CONTACT"" }] } ] }, { ""text"": ""USER"", ""column"": ""CLASS"" } ] }"
        Dim o As Object = Nothing
        Try
            ' deserialize the JSON into an Object,
            ' shout out to: https://stackoverflow.com/a/20080495/1129926
            o = jss.Deserialize(Of Object)(jsonData)
            o = jss.Serialize(o)
            Context.Response.Clear()
            Context.Response.ContentType = "application/json; charset=utf-8"
        Catch ex As Exception
            // log something
        End Try
    
        Return o
    
    End Function
    

    在客户端上,我在脚本块中初始化了 jsTree,如下所示:

    $(document).ready(function () {
        var sURL = "../dataIO.asmx/GetJsonData";
        var dataIn = "";
        $.ajax({
            async: true,
            type: "POST",
            url: sURL,
            dataType: "json",
            data: dataIn,
            contentType: "application/json; charset=utf-8",
            success: function (data) {
                console.log("data obj:" + data);
                createJSTrees(data);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.statusText + "(status=" + XMLHttpRequest.status + "): " + XMLHttpRequest.responseText);
            }
        });
    });
    function createJSTrees(jsonData) {
        $("#jstree_dataNav").jstree({
            "core": {
                "data": jsonData
            }
        });
        $("#jstree_dataNav").on("changed.jstree", function (e, data) {
            console.log(data.selected);
        });
    }
    
    <div id="jstree_dataNav"></div>
    

    jsTree 有一些替代语法,而您在 core.data 部分中调用 Web 服务,但我无法让它工作。相反,我通过 ajax 调用我的 Web 服务,然后将 JSON 数据对象传递给初始化 jsTree 插件的函数,而 jsTree 只是使用数据中传入的对象:。

    【讨论】:

      猜你喜欢
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      相关资源
      最近更新 更多