通过WCF REST服务进行ASP.NET延迟内容加载






4.89/5 (12投票s)
使用 WCF REST 服务实现 jQuery 的 dynatree 插件以惰性加载子节点
引言
网页内容的延迟加载基本上是指在需要内容之前推迟加载。我们将尝试通过一个名为Dynatree的jQuery插件在网页中实现这种延迟内容加载的概念。
Dynatree是一个开源的jQuery树插件,它允许使用JavaScript动态创建HTML树视图控件。可以在http://dynatree.googlecode.com上找到更多详细信息。
我们将通过使用WCF编写的REST服务来实现分支的延迟加载。树节点的Data transfer将通过JSON完成。
我选择REST服务而不是传统的Web服务,是因为;REST服务是共享数据的更好、更简单的选择。为了实现REST服务,.NET 3.5在WCF中引入了webHttpBindings
。此绑定有助于按照REST的标准发布我们的普通WCF服务。
什么是REST服务?
REST代表表征状态转移,这意味着每个唯一的URL代表某个对象。任何REST服务都可以使用标准的HTTP GET
或POST
请求来访问。REST服务是轻量级的,因为没有使用额外的XML标记进行传输,并且结果易于理解且人类可读。
输出

开发环境
- 框架:.NET 3.5
- 环境:VS 2008
- 语言:C#
- jQuery Framework版本:v1.3.2
先决条件
- 基本的WCF知识
- 基本的jQuery知识
创建项目
创建一个名为“LazyLoading
”的新ASP.NET Web应用程序。
树节点类
现在我们将定义一个类来存储节点数据,该类将用于以JSON的形式将信息从服务器传递给客户端。
在项目中添加一个名为“TreeNode
”的类。该类将如下所示
public class TreeNode
{
///<summary>
/// Title of the Node
///<summary>
public string title { get; set; }
///<summary>
/// Parent node of leaf node.
///<summary>
public bool isFolder { get; set; }
///<summary>
/// Lazy loading enabled or not.
///<summary>
public bool isLazy { get; set; }
///<summary>
/// Hidden id of the Node
///<summary>
public string key { get; set; }
}
启用AJAX的WCF服务
现在,我们将在项目中添加一个启用了AJAX的WCF服务,名为TS.svc。

TS.svc将是服务文件,我们将在其中定义可以从jQuery调用的方法。在我们的例子中,我们只有一个名为GetNode
的方法,该方法接受“key”参数,并根据key生成树的节点,并将TreeNode
的列表返回给调用者。
为了获取节点列表,我们的客户端将向我们的REST服务发出如下请求
- https://:5678/TS.svc/GetNodes/1 - 加载所有根节点
- https://:5678/TS.svc/GetNodes/11234 - 加载ID为11234的节点的子节点
我们的WCF服务的代码如下
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TS
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "GetNodes/{key}",
BodyStyle = WebMessageBodyStyle.Bare)]
public List<TreeNode> GetNodes(string key)
{
Thread.Sleep(1000); // For showing the delay effect
List<TreeNode> collection = new List<TreeNode>();
string NodeTitle = string.Empty;
//Generate the title of the node
if (key.Equals("1"))
{
NodeTitle = "Root";
}
else
{
NodeTitle = string.Format("Child Key-{0}", key);
}
//Generate some random nodes
for (int i = 1; i <= new Random().Next(15); i++)
{
int rC = new Random().Next(3) + 1;
collection.Add(
new TreeNode()
{
isFolder = (i % rC != 0),
isLazy = (i % rC != 0),
key = string.Format
("{0}{1}", key, i),
title = string.Format("{0}-[{1}]",
NodeTitle, i)
}
);
}
return collection;
}
}
在上面的代码中,您可以找到一些使用的属性。请在下面找到每个属性的详细信息
AspNetCompatibilityRequirementsMode
:然后,您可以将显式属性添加到您的实现类中,以使ASP.NET上下文在您的应用程序中可用
ServiceContract
:要指定的服务的命名空间。我们使用空白,因为它是一个测试服务,不包含任何URI格式。
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "GetNodes/{key}",
BodyStyle = WebMessageBodyStyle.Bare)]
在GetNodes
方法中,我们使用WebInvoke
属性对其进行修饰,以指定该方法将使用标准HTTP GET
请求访问,并且方法调用的输出以JSON的形式呈现。UriTemplate
指定访问服务的路径和格式。UriTemplate
类帮助我们定义Uri格式字符串和Uri中的模板文本。在我们的例子中是GetNodes/{key}
,其中key将在调用服务时动态替换。
在JSON中,裸格式意味着通用的JSON对象,没有WCF附加的任何额外内容。以下是我们的GetNodes
方法生成的示例裸JSON。

为了进行测试,我们可以通过简单地调用https://:5678/TS.svc/GetNodes/1来访问它。
WCF 配置
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="LazyLoading.TSAspNetAjaxBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="TimeTrakkerServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="LazyLoading.TS" behaviorConfiguration="TimeTrakkerServiceBehavior" >
<endpoint behaviorConfiguration="LazyLoading.TSAspNetAjaxBehavior"
binding="webHttpBinding" contract="LazyLoading.TS" />
</service>
</services>
</system.serviceModel>
对于我们的REST服务,我们使用WebHttpBinding
作为绑定,因为我们需要配置通过HTTP GET
请求公开的端点,而不是传统的SOAP消息。其余配置很简单。
客户端代码
在页面中包含jQuery框架和dynatree插件。
<link href="CSS/Jquery.css" rel="stylesheet" type="text/css" />
<script src="Script/jquery.js" type="text/javascript"></script>
<script src="Script/ui.core.js" type="text/javascript"></script>
<script language="jscript" src="Script/jquery.dynatree.js"
type="text/javascript"></script>
JavaScript
$("#tree").dynatree({
title: "Lazy Tree",
rootVisible: true,
fx: { height: "toggle", duration: 200 },
initAjax: {
url: "TS.svc/GetNodes/1"
},
在这里,我们通过提供key作为1来传递URL;这将加载我们树的所有根节点。
onActivate: function(dtnode) {
$("#echoActive").text(dtnode.data.title);
},
onActivate
函数将有所帮助,如果我们想处理任何节点上的点击事件,例如,我们想根据节点点击加载其他内容,那么可以使用此函数,我们可以获取当前选定的节点id dtnode.data.key
和标题 dtnode.data.title
。
onLazyRead: function(dtnode) {
dtnode.appendAjax({
url: "TS.svc/GetNodes/" + dtnode.data.key
});
}
如果我们在树的任何懒加载节点上单击,则会触发onLazyRead
,在这里我们通过传递节点的key来调用我们的GetNode
方法。
结论
本文是jQuery dynatree插件的ASP.NET实现。作为一名Web开发人员,很多时候我们需要开发这样的树,对于大型树结构来说,出于性能原因,延迟加载变得非常必要。