4

私は 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 に設定すると機能しなかったため、これを機能させるのにしばらく苦労しました。これは私が期待するものです。そのような状況では、json 応答を解析するときに Web サービスまたは jQuery によってエラーは報告されませんが、ツリーは空になります。

Web サービスの HTML 出力を見ると、どちらの方法でレンダリングされたものにも違いは見られませんでした。これが機能する理由 (直感に反して) と、ResponseFormat.Json で機能しない理由を誰かが説明できることを期待していました。

質問 2:一般的に、Web サービスまたは Web ハンドラーですか?

とにかく、汎用 Web ハンドラー (ashx) を使用すると、より効率的な方法になりますか? 標準の Web サービスと一般的な Web ハンドラーで必要なオーバーヘッドに大きな違いはありますか? 私の目標は基本的に出力されるものを正確に制御することなので (そして、Web サービスで json データ形式を使用しても、とにかく思い通りに動作していないようです)、もしあれば、どのような利点があるのか​​ わかりません。完全に削除するのではなく、ここで Web サービスを使用します。一方、これは今ではうまくいっているので、たぶん私は十分に放っておくべきです.

4

3 に答える 3

4

この質問には約 600 回のビューがあり、回答がないので、自分で答えようと思いました (ずっと前から考えていたので)。

を使用することScriptMethodは、jQuery ajax と通信するための正しい方法ではありません。それは可能ですが、上記で行ったことは、string自分自身を JSON にエンコードした with データを返すことに気付くでしょう。JavascriptSerializer.

ただし、 を使用するScriptMethod と、Microsoft の AJAX フレームワークと通信するように設計されたシリアライゼーション/デシリアライゼーションが自動的に組み込まれます。オブジェクト ラッパーを使用せずに純粋な文字列をシリアル化すると、通常は同じ文字列が返されるため (XML または JSON 形式を返す場合)、基本的には機能しましたが、内部で実際に起こっていたのは、2 回シリアル化されていたことです。

したがって、少なくとも次のことを行う必要がありました。

public List<jsTreeNode> GetChildren(string id)

つまり、戻り値の型は、シリアル化されたデータの文字列ではなく、実際のデータ型である必要があります。

ただし、Microsoft のメソッドは戻り値を object でラップするため、これはまだ正確ではありませんd。Javascript でそれを抽出して、内部データを取得することもできます。しかし、jsTree のようなものが事前定義された形式のデータを期待している場合、これは機能しない可能性があります。

最善の解決策は、WebServices を使用せず、代わりに汎用ハンドラー (ashx) を使用することです。これにより、入力と出力の形式と処理を完全に制御できます。適切なフレームワークをセットアップするには少し手間がかかるかもしれませんが、必要のない WebService 処理の一部をスキップできないというフラストレーションは、それだけの価値があります。

于 2011-04-12T13:12:35.803 に答える
1

申し訳ありませんが、3.5 フレームワークは Json シリアライゼーションと Web サービスを非常によくサポートしています (2.0 では Newtonsoft.Json を使用できます)。http://code.zyky.com/jsTreeView/Default.aspxおよびhttp://asp-net-elephant.blogspot.com/2012/01/how-to-useで私の JsTree ASP.NET Web コントロールのデモを参照してください。両方の例については、-jstree-in-aspnet-web-forms.htmlを参照してください。お役に立てれば。

于 2012-03-08T19:53:15.177 に答える
0

質問 1 (Q2 とは話せません) に関しては、JSON を jsTree プラグインにフィードバックする Web サービスを入手しました。WCF と REST の方が最新のアプローチであり、長期的には間違いなく優れていることは認識していますが、私たちはまだ asmx Web サービスを使用しており、仕事を成し遂げています。しかし、それは簡単ではありませんでした。jsTree が ASP.NET Web サービスからデータ オブジェクトを取得できるように、JS で動作する正確な構文を取得するためにしばらく時間を費やしました。OPが彼のソリューションで暗示しているように、問題は私のJSとプラグインの配線ではなく、私のWebサービスに返された不安定なJSONデータにありました。これは JSON のように見えましたが、簡素化された JSON オブジェクトの文字列表現でした。

それを修正するには、json文字列をデシリアライズしてシリアライズする必要がありました(https://stackoverflow.com/a/20080495/1129926から手がかりを得ました)。結果​​のオブジェクトはjsTreeによって喜んで消費されました。これが私のWebサービスです:

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 は data: 内で渡されたオブジェクトを使用しました。

于 2016-03-03T02:11:21.187 に答える