jquery + jstree в .net - формат ответа веб-сервиса? - PullRequest
4 голосов
/ 19 октября 2010

Я впервые играю с jstree (1.0rc2) + jquery (1.4.2) с c # .net, и хотя у меня все получилось, есть пара вещей, которые я не понимаю о том, как данныепредоставляется дереву веб-сервисом, который я использую для заполнения дерева (используя 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, что я и ожидал.В этой ситуации веб-служба или jQuery не будут сообщать об ошибках при синтаксическом анализе ответа json, но дерево будет отображаться пустым.

При просмотре вывода HTML веб-службы я не вижуРазница между тем, что было оказано в любом случае.Я надеялся, что кто-нибудь сможет объяснить, почему это работает (нелогично) и почему оно не работает с ResponseFormat.Json, и если это указывает на что-то еще, я могу ошибаться.

Вопрос 2: Как правило, веб-сервис или веб-обработчик?

Будет ли использование универсального веб-обработчика (ashx) более эффективным способом сделать это в любом случае?Есть ли существенная разница в накладных расходах, требуемых от стандартного веб-сервиса, по сравнению с обычным веб-обработчиком?Поскольку моя цель в основном состоит в том, чтобы точно контролировать то, что выводится (и использование формата данных json в веб-службе, похоже, не работает так, как мне этого хочется), я не уверен, какая выгода, если таковая имеется,используя веб-сервис здесь, вместо того, чтобы просто удалить его полностью.С другой стороны, теперь это работает, так что, может быть, мне стоит оставить себя в покое.

Ответы [ 3 ]

4 голосов
/ 12 апреля 2011

Поскольку этот вопрос имеет почти 600 просмотров и ответов нет, я подумал, что отвечу на него сам (поскольку я уже давно понял).

Использование ScriptMethod на самом деле не правильный путьобщаться с JQuery AJAX.Хотя это можно сделать, вы заметите, что я делал выше, возвращая string с данными, которые я сам кодировал в JSON, используя JavascriptSerializer.

Однако использование ScriptMethod автоматически включает сериализацию / десериализациюразработан для взаимодействия с Microsoft AJAX.Поскольку сериализация чистой строки без объектной обертки обычно приводит к одной и той же строке (независимо от того, возвращаю ли я формат XML или JSON), она в основном работала, но на самом деле внутренне происходило то, что она сериализовалась дважды .

Итак, что я должен был сделать, как минимум:

public List<jsTreeNode> GetChildren(string id)

, то есть тип возвращаемого значения должен быть фактическим типом данных, а не строкойсериализованных данных.

Однако это все равно будет не совсем правильно, поскольку методы Microsoft заключают возвращаемое значение в объект d.Я все еще могу извлечь это в Javascript, чтобы получить внутренние данные.Но если что-то вроде jsTree ожидает данные в предопределенном формате, это может не сработать.

Лучшее решение - не использовать WebServices, вместо этого используйте универсальные обработчики (ashx). Это дает вамполный контроль над форматом и обработки вашего ввода и вывода.Может потребоваться немного усилий, чтобы настроить себе хорошую среду, но разочарование в связи с невозможностью пропустить части обработки WebService, в которых вы не нуждаетесь, делает его вполне оправданным.

1 голос
/ 08 марта 2012

Извините, я должен не согласиться с вашим ответом. Фреймворк 3.5 действительно хорошо поддерживает сериализацию и веб-службы Json (а для 2.0 вы можете использовать Newtonsoft.Json). Пожалуйста, ознакомьтесь с моей демонстрацией JsTree ASP.NET Web Control на http://code.zyky.com/jsTreeView/Default.aspx и http://asp -net-elephant.blogspot.com / 2012/01 / как использовать jstree-in-aspnet-web -forms.html для примера обоих. Надеюсь, это поможет.

0 голосов
/ 03 марта 2016

Относительно вопроса 1 (я не могу говорить с Q2), я получил веб-сервис для передачи JSON обратно в плагин jsTree. Хотя я признаю, что WCF и REST являются более актуальными подходами, и, без сомнения, лучше в долгосрочной перспективе, мы все еще используем веб-сервисы asmx, и они выполняют свою работу. Но это было нелегко: я потратил некоторое время, пытаясь заставить точный синтаксис работать в JS, чтобы jsTree получал свой объект данных из веб-службы ASP.NET. Как указывает OP в своем решении, проблема не столько в моем JS и подключении плагина, сколько в шатких данных 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, но я не смог заставить его работать. Вместо этого я вызываю свой веб-сервис через ajax, а затем передаю объект данных JSON в функцию, которая инициализирует плагин jsTree, а jsTree просто использует объект, переданный внутри данных:.

...