用JS + WCF打造轻量级WebPart

自打.net2.0起,ms就推出了webPart功能,用它可以轻松开发出具有web2.0风格的个性化网站功能,比如拖放,定制标题栏等,但是WebPart的设计是属于重量级的,每次拖动都会引起页面回发,导致数据库读写以及大量的数据传输(即使在最外层套一个MajicAjax之类的,也是如此),另外WebPart在非IE标准浏览器上有些功能也不能正常使用。而网上流传的众多JS实现的特效功能中,已经有很多不错的JS源码,其实我们只要结合.net的功能修改一下,就能达到类似WebPart的功能,而且这种实现完全是轻量级的。


先来看下http://www.jscode.cn/jave_page/300804727.htm这上面的拖放特效(muxrwc兄的作品,博客地址http://blog.csdn.net/muxrwc),这上面已经实现得很不错的,布局的保存是用cookie实现

的,我们把它修改为利用数据库保存(主要思路就是保存布局时把cookie字符串存到数据库中,加载时从数据库里取出数据初始化),修改后的演示效果地址为http://ext.cneds.net(随时可能会被停掉,呵呵)

1.数据库结构:
(1)布局表T_LayOut

CREATE TABLE [dbo].[T_LayOut](
 [F_ID] [int] IDENTITY(1,1) NOT NULL,
 [F_LayOut] [nvarchar](max) COLLATE Chinese_PRC_CI_AS NOT NULL,
 CONSTRAINT [PK_T_LayOut] PRIMARY KEY CLUSTERED
(
 [F_ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]


(2)新闻表T_News

 CREATE TABLE [dbo].[T_News](
 [ID] [int] IDENTITY(1,1) NOT NULL,
 [Title] [nvarchar](200) COLLATE Chinese_PRC_CI_AS NULL,
 CONSTRAINT [PK_T_News] PRIMARY KEY CLUSTERED
(
 [ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

 

2.WCF部分
(1)新建一个启用了Ajax的WCF:MyData.svc
svc文件中,修改为
<%@ ServiceHost Language="C#" Debug="true" Service="GetData" CodeBehind="~/App_Code/GetData.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

web.config中手动修改节点,参考以下:

   
    
                        
    

   

  


(2)新建几个方法:


//取得页面布局数据
[OperationContract]
[WebInvoke(ResponseFormat
= WebMessageFormat.Json, UriTemplate = "GetLayOutById?id={id}", Method = "GET")]
public Stream GetLayOutById(int id)
{
//System.Threading.Thread.Sleep(2000);
string _Result = "";
using (DBDataContext db = new DBDataContext())
{
try
{
_Result
= db.T_LayOuts.Where(c => c.F_ID == id).Select(c => c.F_LayOut).First();
}
catch { }
finally { db.Connection.Close(); }
}

MemoryStream ms
= new MemoryStream();
StreamWriter sw
= new StreamWriter(ms);
sw.AutoFlush
= true;
sw.Write(_Result);
ms.Position
= 0;
WebOperationContext.Current.OutgoingResponse.ContentType
= "text/plain";
return ms;
}

//保存布局
[OperationContract]
[WebInvoke(ResponseFormat
= WebMessageFormat.Json, UriTemplate = "SaveLayOutById?id={id}&layout={layout}", Method = "GET")]
public string SaveLayOutById(int id,string layout)
{
string _Result = "false";
using (DBDataContext db = new DBDataContext())
{
try
{
var _layout
= db.T_LayOuts.Where(c => c.F_ID == id).Single();
_layout.F_LayOut
= layout;
db.SubmitChanges();
_Result
= "true";
}
catch { }
finally { db.Connection.Close(); }
}
return _Result;
}


//取得新闻
[OperationContract]
[WebInvoke(ResponseFormat
= WebMessageFormat.Json, UriTemplate = "GetNews?id={id}&limit={limit}", Method = "GET")]
public Stream GetNews(int id,int limit)
{
string _Result = "";
using (DBDataContext db = new DBDataContext())
{
try
{
var query
= db.T_News.Select(c => c.Title).Take(limit).ToList();
for (int i = 0; i < query.Count; i++)
{
_Result
+= query[i] + "
";
}
}
catch { }
finally { db.Connection.Close(); }
}

MemoryStream ms
= new MemoryStream();
StreamWriter sw
= new StreamWriter(ms);
sw.AutoFlush
= true;
sw.Write(_Result);
ms.Position
= 0;
WebOperationContext.Current.OutgoingResponse.ContentType
= "text/plain";
return ms;
}


//取得图片地址
[OperationContract]
[WebInvoke(ResponseFormat
= WebMessageFormat.Json, UriTemplate = "GetPic", Method = "GET")]
public string GetPic()
{
return "http://www.baidu.com/img/baidu_logo.gif";
}


3.JS部分

(1)页面上增加一个按钮


(2)对应的增加处理的js函数


(function(wc) {
$(
"DEL_CDrag").onclick = function() {
wc.del_cookie();
window.location.reload();
};
$(
"ADD_CDrag").onclick = function() {
wc.append();
};
$(
"Save_CDrag").onclick = function() {
_cookie =
wc.get_cookie();
_url = "WCF/GetData.svc/SaveLayOutById?id=" + encodeURIComponent(id) + "&layout=" + encodeURIComponent(_cookie) + "&time="
;
_callBack = function
(str) {
if (str == "/"true/""
) {
alert("布局保存成功!"
);
disableSaveButton();
}
else
{
alert("布局保存失败!"
);
}
};

_ajax.initialize(_url);
_ajax.send(_url, _callBack);
}
})(_wc);

大意:利用CDrag扩展的Ajax功能,向WCF/GetData.svc/SaveLayOutById提交cookie数据写到数据库,再根据返回值给出提示

(3)页面初始加载函数修改


Object.addEvent(window, ["onload"], function() {

$(
"loading").innerHTML = "布局加载中";

var _wc = new CDrag, _ajax = CDrag.Ajax.prototype, _cookie = _wc.get_cookie(), _callBack = null, _url = ""
;

_url
= "WCF/GetData.svc/GetLayOutById?id=" + encodeURIComponent(id) + "&time="
;

//加载完成的回调函数

_callBack = function(str) {
_cookie
=
str;
json
= _cookie ?
_wc.parse_json(unescape(_cookie)) : [
{ cols:
"m_1"
, rows: [
{ id:
"m_1_1", window: 1, locks: false
},
{ id:
"m_1_2", window: 1, locks: false
},
{ id:
"m_1_3", window: 1, locks: false
}
]
}, {
cols:
"m_2"
, rows: [
{ id:
"m_2_1", window: 1, locks: false
},
{ id:
"m_2_2", window: 1, locks: false
},
{ id:
"m_2_3", window: 1, locks: false
}
]
},
{ cols:
"m_3"
, rows: [
{ id:
"m_3_1", window: 1, locks: false
},
{ id:
"m_3_2", window: 1, locks: false
},
{ id:
"m_3_3", window: 1, locks: false
}
]
}
];
_wc.parse(json);
(
function(wc) {
$(
"DEL_CDrag").onclick = function() {
wc.del_cookie();
window.location.reload();
};
$(
"ADD_CDrag").onclick = function() {
wc.append();
};
$(
"Save_CDrag").onclick = function() {
_cookie
= wc.get_cookie();
_url
= "WCF/GetData.svc/SaveLayOutById?id=" + encodeURIComponent(id) + "&layout=" + encodeURIComponent(_cookie) + "&time=";
_callBack
= function(str) {
if (str == "/"true/"") {
alert(
"布局保存成功!");
disableSaveButton();
}
else {
alert(
"布局保存失败!");
}
};

_ajax.initialize(_url);
_ajax.send(_url, _callBack);
}
})(_wc);
_wc
= null;
$(
"loading").innerHTML = "";
}
_ajax.initialize(_url);
_ajax.send(_url, _callBack);
});

同样,也是利用Ajax来加载布局数据

4.源代码下载:
http://ext.cneds.net/src/dragdrop.rar (要下载的抓紧,公司的域名临时拿来用的,随时可以会停掉)

转载请注明来自菩提树下的杨过http://www.cnblogs.com/yjmyzz/archive/2008/09/20/1294753.html

后记:
其实本文没有什么特殊的技术含量,就是WCF与AJAX的常规应用,大家回去多演练几遍,自然也就熟能生巧了,其实感觉WCF的使用到不算很复杂,JS才是考验web应用真功夫的地方(特别是web 2.0的网站).

你可能感兴趣的:(.Net/C#/APSX)