我第一次使用c#.net玩jstree(1.0rc2)+ jquery(1.4.2),尽管我已经开始工作了,但我还是有几件事我不了解数据如何由我用来填充树的webservice提供给树(使用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处理程序(ashx)是否会更有效地执行此操作?标准Web服务与通用Web处理程序所需的开销是否存在实质性差异?因为我的目标基本上是控制输出的确切内容(并且在Web服务中使用json数据格式似乎并不像我想要的那样工作)我不确定有什么好处,如果有的话,那就是在这里使用Web服务而不是完全剥离它。另一方面,这现在有效,所以也许我应该留下足够好的。
答案 0 :(得分:4)
看到这个问题有近600个观点,没有答案,我想我会自己回答(因为我早就认识到了)。
使用ScriptMethod
实际上不是与jQuery ajax通信的正确方法。虽然可以这样做,但您会注意到我上面所做的是返回一个string
,其中包含我使用JavascriptSerializer.
但是,使用ScriptMethod
自动合并序列化/反序列化,旨在与Microsoft的AJAX框架进行通信。由于序列化没有对象包装器的纯字符串通常会产生相同的字符串(无论我是返回XML还是JSON格式),它基本上都有效,但内部真正发生的事情是它被序列化两次
所以我应该做的至少是:
public List<jsTreeNode> GetChildren(string id)
也就是说,返回类型应该是实际的数据类型,而不是一串序列化数据。
然而,这仍然不完全正确,因为Microsoft的方法将返回值包装在对象d
中。我仍然可以在Javascript中提取它来获取内部数据。但是,如果像jsTree这样的东西期望以预定义的格式生成数据,那么这可能是行不通的。
最佳解决方案是不使用Web服务,而是使用通用处理程序(ashx)。这使您可以完全控制输入和输出的格式和处理。为自己设置一个不错的框架可能需要做一些工作,但是无法跳过你不需要的部分WebService处理的挫败感使它非常值得。
答案 1 :(得分: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-in-aspnet-web-forms.html上的JsTree ASP.NET Web控件演示,以获取两者的示例。希望这会有所帮助。
答案 2 :(得分:0)
关于问题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只使用在数据中传入的对象:。