您的位置:首页 > 编程语言 > ASP

ASP.NET AJAX CodePlex Preview 3的代码解析

2008-11-13 20:01 375 查看

source:/article/5087952.html

ASP.NET AJAX CodePlex Preview 3的代码解析

Posted on 2008-11-13 11:12 Kevin-moon 阅读(623) 评论(3) 编辑 收藏 网摘 所属分类: 网站设计


忙了半个月,现在终于闲下来了,有时间写博,感觉真爽!刚刚看到有人想一起研究ASP.NET AJAX CodePlex Preview 3的帖子,正好前段时间小研究了下.Preview3就出了两个JS(MicrosoftAjaxAdoNet.js和MicrosoftAjaxTemplates.js).
这里先介绍下MicrosoftAjaxAdoNet类库,对于它的介绍在MS提供的文档中都说明了.这里只是解析下代码,并一起讨论下.先放一张这个类库中的类关系图上来



下面看下它的基础类:

AdoNetQueryBuilder类:
主要属性:
_queryParameters: uri的?之后的参数数组
_uri: uri的?之前的地址
用处:
对URL的分解,根据查询的参数(?之后)创建参数数组(array),同时也可以设置$skip,$top,$orderby,$filter,$expand这些参数,但是这些参数如何使用的,还不清楚!?
在该类库中还用在AdoNetServiceProxy的invoke服务,用于分解参数operationUri.

AdoNetActionResult类
主要属性:
_actionContext, _error, _operation, _result
用处:
AdoNetActionSequence队列执行完动作后,成功/失败的回调函数返回的结果对象.

_AdoNetUtil类
这是是内部使用的类,主要包括三个方法
concatUris(serviceUri, resourceUri): 合并两个uri
extractETag: 获取item对象的etag属性.(item对象是AdoNetServiceProxy中传给每个服务[insert,update...]的内容参数)
extractUri: 获取item对象内__metadata的uri属性

AdoNetServiceError类
属性:
_errorObject: 异常对象
_message: 异常信息
_statusCode: 状态码
_timedOut: 请求是否超时
用处:
AdoNetServiceProxy中服务请求服务器的过程中,请求失败返回的异常对象

核心的类:

AdoNetActionSequence类:
主要属性:
_actionQueue: 服务队列
_dataService: AdoNetServiceProxy对象
addInsertAction: 将AdoNetServiceProxy的insert服务加入队列,
addInvokeAction: 将AdoNetServiceProxy的invoke服务加入队列,
addUpdateAction: 将AdoNetServiceProxy的update服务加入队列,
addRemoveAction: 将AdoNetServiceProxy的remove服务加入队列,
clearActions: 清除队列中的所有服务
execute: 批量执行队列中的每个服务
作用:
动作的队列,可以利用add...这些方法将insertAction,InvokeAction,UpdateAction,RemoveAction这些动作放到数组里面,然后再通过execute批量执行. 也就是提供个批量管理和执行服务的接口.
下面是addInsertAction的方法中加入队列的CODE,其他的代码类试:




Code
//AdoNetServiceProxy服务代理对象
var dataService = this._dataService;

Array.enqueue(this._actionQueue,
function(o) {
//dataService的insert服务
dataService.insert(
item,
resourceSetUri,
Sys.Data.AdoNetActionSequence._genSuccessCallback(o),
Sys.Data.AdoNetActionSequence._genFailureCallback(o),
actionContext
)
}
);

AdoNetServiceProxy类:
主要属性:
_defaultFailedCallback: 失败的回调函数
_defaultSucceededCallback: 成功的回调函数
_defaultUserContext:
_serviceUri: 服务器的Uri
_timeout: Ajax请求的超时时间
_usePostTunneling:

方法:
createActionSequence: 创建服务队列
_prepareWebRequest: 构造WebRequest对象
insert服务:(item, resourceSetUri, succeededCallback, failedCallback, userContext, webRequest)
invoke服务:(operationUri, httpVerb, parameters, succeededCallback, failedCallback, userContext, webRequest)
remove服务:(item, succeededCallback, failedCallback, userContext, webRequest)
update服务:(item, succeededCallback, failedCallback, userContext, webRequest)
query服务: (query, succeededCallback, failedCallback, userContext, webRequest)

这是类库中最核心的类,提供了允许和服务器交互的各种服务.同时也是最复杂的类.大家先看下_prepareWebRequest这是每个服务都要首先调用的方法,因为每个服务都要构造自己的WebRequest对象.




Code
function Sys$Data$AdoNetServiceProxy$_prepareWebRequest(item, relativeUri, verb, onSuccess, onFailure, context, operation, webRequest) {
webRequest = webRequest || new Sys.Net.WebRequest();
webRequest.set_url(Sys.Data._AdoNetUtil.concatUris(this._serviceUri, relativeUri || ""));
webRequest.set_timeout(this.get_timeout());

var headers = webRequest.get_headers();
headers["Accept"] = "application/json";
headers["DataServiceVersion"] = "1.0;AspNetAjax";
headers["MaxDataServiceVersion"] = "1.0;";

webRequest.set_httpVerb(verb);
if (this._usePostTunneling) {
var verbUpper = verb.toUpperCase();
if ((verbUpper == "PUT") || (verbUpper == "DELETE") || (verbUpper == "MERGE")) {
webRequest.set_httpVerb("POST");
headers["X-HTTP-Method"] = verbUpper;
}
}

if (item) {
webRequest.set_body(Sys.Serialization.JavaScriptSerializer.serialize(item));
headers["Content-Type"] = "application/json";

var eTag = Sys.Data._AdoNetUtil.extractETag(item);
if (eTag) {
headers["If-Match"] = eTag;
}

var uri = Sys.Data._AdoNetUtil.extractUri(item);
if (uri) {
webRequest.set_url(uri);
}
}

onSuccess = onSuccess || this._defaultSucceededCallback;
onFailure = onFailure || this._defaultFailedCallback;
if ((typeof(context) === "undefined") || (context === null)) {
context = this._defaultUserContext;
}

webRequest.add_completed(Function.createDelegate(this, function(executor) {
this._onResponseComplete(executor, onSuccess, onFailure, context, operation);
}));
return webRequest;
}

看完了吧,先讲下_prepareWebRequest的参数:
参数item: 1, 等待新增/修改/删除的对象,它将被序列化为JSON,然后被设置到webrequest的body上
2, 如果item中存在__Metedate,并且它的uri也存在的话,那么将该对象的uri赋予到webrequest上.
参数relativeUri: 请求的相对地址,并和_serviceUri属性一起构成webrequest的uri
参数verb: Web请求的类型(GET/POST)
其他的参数都是和回调函数有关的参数,比较容易的.

在这个地方,我一直有点不理解的地方,就是webrequest的set_uri,它是设定服务器的Uri,但是在这里这个地址来源与item对象中的__Metedate和relativeUri,而且__Metedate的优先级更高,大家再看下上面每个服务的参数,就insert服务有relativeUri这个参数,其他的例如udpate,remove服务都没有这个参数,它们都是需要来自__Metedate.Uri, MS为什么需要这样?一直没有想明白......
好了,现在去看MicrosoftAjaxTemplates.js了,呵呵!刚刚看完,就写出来了,所以如果有什么理解不对的地方,大家一起讨论下,呵呵!

Feedback

#1楼 回复 引用

2008-11-13 11:29 by SH11111111111111Y [未注册用户]
我是沙发吗

#2楼 回复 引用

2008-11-13 11:37 by 小菜000 [未注册用户]
不错 先支持下

#3楼 回复 引用

2008-11-13 14:19 by 不知对方 [未注册用户]
喜欢这样的帖子
极其讨厌那种“出版直播”
广告性极强而且毫无内容
书要写的好还要靠这个?
当然可能与作者没有关系,都是出版社的错
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: