通过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开发人员,很多时候我们需要开发这样的树,对于大型树结构来说,出于性能原因,延迟加载变得非常必要。


