AJAX之内部揭秘,新瓶旧酒ASP

原稿地址:http://www.codeproject.com/KB/ajax/aspnetajaxtips.aspx
[初稿源码下载]

[索引页] [源码下载]

[翻译]ASP.NET AJAX之内部揭秘

新瓶旧酒ASP.NET AJAX(10) – 客户端脚本编制程序(Sys.Services命名空间下的类)

原著宣布日期:二零零五.12.22
作者:About Omar Al
Zabir

翻译:webabcd
审校:Tony Qu 

作者:webabcd

介绍
微软多年来发布了ASP.NET AJAX的Beta
2版。纵然它是1个那些强大的框架,但是当你在web
2.0的社会风气中要费用一个着实的AJAX
web站点的话,就会赶上许多题材,而且你大约找不到其余相关文书档案。本文中,笔者将介绍一些在开发Pageflakes中所学习到的高档经验。大家将会看到ASP.NET
AJAX一些意义的得失,如批调用(Batch
Call),调用超时,浏览器调用拥堵难题,ASP.NET 2.0中web
service响应缓存的bug等等。

介绍
ASP.NET
AJAX的Sys.Services.AuthenticationService类、Sys.Services.ProfileService类、Sys.Services.ProfileGroup类完美地和ASP.NET
2.0的Membership和Profile进行了合并

正文最后更新:二零零六年三月1日,针对ASP.NET AJAX
PRADOC更新(译注:适用于ASP.NET AJAX v1.0)

关键
1、Sys.Services.AuthenticationService类的login()方法
    Sys.Services.AuthenticationService.login(userName, password,
isPersistent, customInfo, redirectUrl, loginCompletedCallback,
failedCallback, userContext);
    ·userName – 用户名
    ·password – 密码
    ·isPersistent – 是不是跨浏览器保存认证消息(持久保留)
    ·customInfo – 保留字段,或者在今后选取
    ·redirectUrl – 登录成功后重定向到的U途睿欧L
    ·loginCompletedCallback – 登录成功后的回调函数
    ·failedCallback – 报到战败后的回调函数
    ·userContext – 用户上下文
    WebService中与其对应的措施 – public bool Login()

为啥要运用ASP.NET AJAX
有个外人在阅览Pageflakes的时候,首先问小编的标题正是“为啥不行使Protopage也许Dojo库?而是Atlas?”微软的Atlas(已重命名为ASP.NET
AJAX)是三个卓越有前途的AJAX框架。微软为了那么些框架做了好多努力,制作了汪洋可选用的零部件,那样能够减弱你的成本时间,那样的话,只要很少的工作量即可让您的web应用程序有1个周全的界面。它与ASP.NET融合为一,并且包容ASP.NET的Membership和Profile。AJAX
Control
Toolkit
品类包涵了26个扩大(译注:未来有33个),你能够把它们拖拽到页面上,然后通过安装某个天性就足以生出11分酷的功能。看看那一个例子你就会领悟ASP.NET
AJAX给大家带来了何等强大的职能。

贰 、登录成功后的回调函数
    function LoginComplete(bool validCredentials, userContext,
methodName)
    ·validCredentials – 是还是不是成功通过了说明
    ·userContext – 用户上下文
    ·methodName – 调用的法门名

在大家最初开发Pageflakes的时候,Atlas还地处幼儿阶段。大家不得不使用page
method和Web
Service方法来调用Atlas的特点。大家只好开发大家和好的拖拽、组件构造、弹出、伸缩/展开等特色。不过以后,Atlas提供了有着那一个功效,所以能够大大节约我们的付出时间。最令人诧异的是Atlas提供了web
service代理的特征。你能够钦赐<script>标签到一个.asmx文本,然后您会获取贰个JavaScript类,它会依照web
service的定义被科学的变动。那使得添加或移除3个web
service变得十三分简单,而且你在web
service中添加或移除方法都不必要客户端作任何变动。Atlas也提供了累累依照AJAX调用的控件,并且提供了在JavaScript中抓获丰富分外音讯的性子。服务器端的10分能够被规范的抛给客户端的JavaScript代码,你能够捕获它们并格式化这么些错误音信,然后呈现给用户。Atlas与ASP.NET
2.0重组起来工作得要命卓越,完全去掉了整合难题。你不要求担心page
method和web
service的印证和授权难点,所以能够大大减弱你的客户端代码的开发量(当然,也便是因为那样,Atlas运转时也变得卓殊巨大),相对于任何的AJAX框架来说,你能够把越多的生命力放到自个儿的代码开发上来。

3、Sys.Services.AuthenticationService类的logout()方法
    Sys.Services.AuthenticationService.logout(redirectUrl,
logoutCompletedCallback, failedCallback, userContext);
    ·redirectUrl – 注销成功后重定向到的URAV4L
    ·logoutCompletedCallback – 注销成功后的回调函数
    ·failedCallback – 撤除战败后的回调函数
    ·userContext – 用户上下文
    Web瑟维斯中与其对应的方式 – public void Logout()

Atlas如今的本子能够与ASP.NET的Membership、Profile完美的结合,为您提供了在JavaScript中登录和收回的表征,而不要发postback给服务器,你也能够平素从JavaScript中读取和写入Profile。当你在web应用程序中央银行使Membership和Profile的时候,那将变得十分不难,例如大家做的Pageflakes

肆 、注销成功后的回调函数
    function LogoutComplete(result, userContext, methodName)
    ·result – 保留字段,可能在以后使用,始终为null
    ·userContext – 用户上下文
    ·methodName – 调用的方法名

在Atlas的早些版本中,没有动用HTTP GET调用的章程。全数的调用都是HTTP
POST,所以调用的代价是老大大的。而前天,你能够说,哪个调用是HTTP
GET的(而哪些不是)。一旦您使用了HTTP
GET,你就可以运用HTTP响应缓存特性,我将高速介绍这一特征。

五 、Sys.瑟维斯s.Authentication瑟维斯类的性质
    ·defaultLoginCompletedCallback – 登录成功后的回调函数
    ·defaultLogoutCompletedCallback – 注销成功后的回调函数
    ·defaultFailedCallback – 报到或吊销失利后的回调函数
    ·isLoggedIn – 当前用户是还是不是早已报到
    ·path – authentication service路径
    ·timeout – 超时时间

批调用并不一定快
ASP.NET
AJAX的CTP版本(此前的版本)里有一个表征,正是同目的在于2个请求里带有八个请求。它工作时您不会小心到别的事情,而且也不须要写任何例外的代码。一旦您利用了批调用特色,那么在三遍批调用时期,个中全体的web
service调用都会被执行,所以它将回落回发时间和总响应时间。

6、Sys.Services.ProfileService类的load()方法
    Sys.Services.ProfileService.load(propertyNames,
loadCompletedCallback, failedCallback, userContext);
    ·propertyNames – Profile属性名称数组
    ·loadCompletedCallback – 成功后的回调函数
    ·failedCallback – 未果后的回调函数
    ·userContext – 用户上下文
    WebService中与其对应的办法 – public IDictionary<string,
object> GetAllPropertiesForCurrentUser()和public
IDictionary<string, object> GetPropertiesForCurrentUser(string[]
properties)

实质上的响应时间或许压缩了,不过大家备感到的推移却变长了。假若有2个web
service被批量调用,那么首先个调用不会发轫完毕,而是具有三个调用会在相同的大运成功。假使您的每四个web
service调用完了后都更新UI的话,将不会一步一步更新,而是在享有调用一起形成后再一并更新UI。结果,你不会看到UI被高效翻新,而是在UI被更新以前有一个长日子的延迟。要是说调用中的任何2个(比如第3个调用)下载了多量数额,那么在拥有的三个调用达成以前用户不会看出任何变更。所以率先个调用的进行时间差不多接近2个调用的总执行时间。即使减弱了实在的总括拍卖时间,但是会深感有更长的延迟。当每种调用都只传输少量多少的时候批调用是可怜好的,这样,二个小型调用就会在一回回发中进行完。

七 、读取Profile成功后的回调函数
    function onLoadCompleted(numProperties, userContext, methodName)
    ·numProperties – 重回的Profile属性个数
    ·userContext – 用户上下文
    ·methodName – 调用的法门名

让大家看看二个调用是哪些叁个二个被成功的,那将表达那个调用实际上是怎么着被执行的。
图片 1

8、Sys.Services.ProfileService类的save()方法
    Sys.Services.ProfileService.load(propertyNames,
saveCompletedCallback, failedCallback, userContext);
    ·propertyNames – Profile属性名称数组
    ·saveCompletedCallback – 成功后的回调函数
    ·failedCallback – 未果后的回调函数
    ·userContext – 用户上下文
    ·WebService中与其对应的格局 – public int
SetPropertiesForCurrentUser(IDictionary<string, object> values)

其次个调用到达服务端的年华要比第二个调用长,因为第贰个调用吃光了带宽。同样的由来,下载也就会花越来越多的岁月。浏览器同时开辟了三个几次三番到劳动器端的连年,所以在同暂时间,只可以处理三个调用。一旦第二个调用或第二个调用完毕后,第7个调用才能被拍卖。

九 、保存Profile成功后的回调函数
    onSaveCompleted(numProperties, userContext, methodName)
    ·numProperties – 保存的Profile属性个数
    ·userContext – 用户上下文
    ·methodName – 调用的法子名

当2个web service在二遍呼吁中被批调用的时候:
图片 2

⑩ 、Sys.Services.ProfileService类的质量
    ·读取或设置有个别Profile的习性要如此写 –
Sys.Services.ProfileService.properties.FieldName; 
    ·defaultLoadCompletedCallback – 读取Profile成功后的回调函数
    ·defaultSaveCompletedCallback – 保存Profile成功后的回调函数
    ·defaultFailedCallback – 读取或保存Profile退步后的回调函数
    ·path – profile service路径
    ·timeout – 超时时间

此处一起下载时间将会持有压缩(要是IIS的削减成效启用的话),并且只需贰遍网络响应。全体的2个调用2遍被发往到服务端后总体举办,组合而成的多个调用的响应是在一遍调用中下载。可是对于用户来讲,他们会觉得速度变慢了,因为UI的换代发生在有着批调用完了今后。这些批调用完了的总时间总是要善用多少个调用的。并且,假使你有雅量的一个又三个的UI更新,IE将会结霜一段时间,那将给用户带来一个不佳的心得。一些时候,时间较长的UI更新会促成浏览器出现“白屏”,不过Fire福克斯和Opera不会有此难点。

11、Sys.Services.ProfileGroup类
    ·定义一个Profile组(同时供给在Web.config中定义)

批调用也是有一些独到之处的。假诺您的IIS启用了gzip压缩功能的话,将对总体结果开始展览削减而不是分别削减每一种结果,那么总下载时间长度就会少于单独调用的下载时间长度。所以,平日批调用都以部分微型调用的话会相比好。可是假如调用会发送或许再次来到较大数目标话,比如20KB,那么最棒就别使用批调用了。批调用还有另二个难点,比如说前七个调用非常的小,第3个调用十分的大,假诺那个调用被批调用的话,那么前八个小的调用就要延期很短日子,因为第二个相当的大。

1② 、登录或吊销战败、读取或保存Profile失利后的回调函数
    function onFailed(error, userContext, methodName)
    ·error – Sys.Net.WebServiceError对象
    ·userContext – 用户上下文
    ·methodName – 调用的主意名

不佳的调用会使好的调用超时
若果有多少个HTTP调用不知缘何执行了很短的时间,那么那三个倒霉的调用也将会使好的调用超时,同时这七个调用会进入队列。那里就有贰个例证:

1叁 、假诺要自行调用相关服务来说,则须要在web.config中的<configuration
/>节点下扩充类似如下的安插

图片 3function TestTimeout()
图片 4图片 5图片 6{
图片 7    debug.trace(“–Start–“);
图片 8    TestService.set_defaultFailedCallback( 
图片 9            function(result, userContext, methodName)
图片 10图片 11    图片 12{
图片 13        var timedOut = result.get_timedOut();
图片 14        if( timedOut )
图片 15            debug.trace( “Timedout: ” + methodName );
图片 16        else
图片 17            debug.trace( “Error: ” + methodName );
图片 18    });
图片 19    TestService.set_defaultSucceededCallback( function(result)
图片 20图片 21    图片 22{
图片 23        debug.trace( result );
图片 24    });
图片 25    
图片 26    TestService.set_timeout(5000);
图片 27    TestService.HelloWorld(“Call 1”);
图片 28    TestService.Timeout(“Call 2”);
图片 29    TestService.Timeout(“Call 3”);
图片 30    TestService.HelloWorld(“Call 4”);
图片 31    TestService.HelloWorld(“Call 5”);
图片 32    TestService.HelloWorld(null); // 那句将招致错误
图片 33}

图片 34<webServices>
图片 35    <authenticationService enabled=”true” requireSSL=”false”/>
图片 36    <profileService enabled=”true” 
图片 37        readAccessProperties=”Age, Salary”
图片 38        writeAccessProperties=”Age, Salary” 
图片 39    />
图片 40</webServices>

服务端的web service也格外简单:

示例
AuthenticationService.asmx

图片 41[WebService(Namespace = “http://tempuri.org/")\]
图片 42[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
图片 43[ScriptService]
图片 44图片 45public class TestService : System.Web.Services.WebService 图片 46{
图片 47
图片 48图片 49    public TestService () 图片 50{
图片 51
图片 52        // 假使利用陈设的组件,请废除注释以下行  
图片 53        // InitializeComponent(); 
图片 54    }
图片 55
图片 56    [WebMethod][ScriptMethod(UseHttpGet=true)]
图片 57图片 58    public string HelloWorld(string param) 图片 59{
图片 60        Thread.Sleep(1000);
图片 61        return param;
图片 62    }
图片 63    
图片 64    [WebMethod][ScriptMethod(UseHttpGet=true)]
图片 65图片 66    public string Timeout(string param) 图片 67{
图片 68        Thread.Sleep(10000);
图片 69        return param;
图片 70    }
图片 71}

图片 72<%@ WebService Language=”C#” Class=”AuthenticationService” %>
图片 73
图片 74using System;
图片 75using System.Web;
图片 76using System.Web.Services;
图片 77using System.Web.Services.Protocols;
图片 78using System.Web.Script.Services;
图片 79
图片 80[WebService(Namespace = “http://tempuri.org/")\]
图片 81[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
图片 82[ScriptService]
图片 83public class AuthenticationService : System.Web.Services.WebService
图片 84图片 85图片 86{
图片 87图片 88    /**//// <summary>
图片 89    /// 登录
图片 90    /// </summary>
图片 91    /// <param name=”userName”>用户名</param>
图片 92    /// <param name=”password”>密码</param>
图片 93    /// <param name=”createPersistentCookie”>是或不是跨浏览器保存认证音讯(持久保留)</param>
图片 94    /// <returns></returns>
图片 95    [WebMethod]
图片 96    public bool Login(string userName, string password, bool createPersistentCookie)
图片 97图片 98    图片 99{
图片 100        //Place code here.
图片 101
图片 102        System.Web.Security.FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
图片 103        return true;
图片 104    }
图片 105
图片 106图片 107    /**//// <summary>
图片 108    /// 注销
图片 109    /// </summary>
图片 110    [WebMethod]
图片 111    public void Logout()
图片 112图片 113    图片 114{
图片 115        //Place code here.
图片 116    }
图片 117}
图片 118
图片 119

本人调用了服务端的名为“Timeout”的章程,它不会做其它业务,而只是等待多个较长的年月以使调用超时。之后,小编再调用1个不会晚点的格局。然则你困惑输出的是如何:
图片 120

ProfileService.asmx

唯有第3个调用成功了。所以,任几时候假设浏览器的三个一连都远在拥堵场合以来,那么你希望的其余调用也都将会晚点。

图片 121<%@ WebService Language=”C#” Class=”ProfileService” %>
图片 122
图片 123using System;
图片 124using System.Web;
图片 125using System.Web.Services;
图片 126using System.Web.Services.Protocols;
图片 127using System.Web.Script.Services;
图片 128using System.Collections.Generic;
图片 129
图片 130[WebService(Namespace = “http://tempuri.org/")\]
图片 131[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
图片 132[ScriptService]
图片 133public class ProfileService : System.Web.Services.WebService
图片 134图片 135图片 136{
图片 137图片 138    /**//// <summary>
图片 139    /// 获取用户的整个Profile
图片 140    /// </summary>
图片 141    /// <returns></returns>
图片 142    [WebMethod]
图片 143    public IDictionary<string, object> GetAllPropertiesForCurrentUser()
图片 144图片 145    图片 146{
图片 147        Dictionary<string, object> dic = new Dictionary<string, object>();
图片 148
图片 149        dic.Add(“Age”, 27);
图片 150        dic.Add(“Salary”, 100);
图片 151
图片 152        Article article = new Article();
图片 153        article.Title = “Article Title From Server”;
图片 154        article.PublishTime = DateTime.Now;
图片 155
图片 156        dic.Add(“Article”, article);
图片 157
图片 158        return dic;
图片 159    }
图片 160
图片 161图片 162    /**//// <summary>
图片 163    /// 获取用户的钦赐的Profile
图片 164    /// </summary>
图片 165    /// <param name=”properties”>属性名称数组</param>
图片 166    /// <returns></returns>
图片 167    [WebMethod]
图片 168    public IDictionary<string, object> GetPropertiesForCurrentUser(string[] properties)
图片 169图片 170    图片 171{
图片 172        //Place code here.
图片 173        return null;
图片 174    }
图片 175
图片 176图片 177    /**//// <summary>
图片 178    /// 保存用户的Profile
图片 179    /// </summary>
图片 180    /// <param name=”values”>用户的Profile的字典数据</param>
图片 181    /// <returns></returns>
图片 182    [WebMethod]
图片 183    public int SetPropertiesForCurrentUser(IDictionary<string, object> values)
图片 184图片 185    图片 186{
图片 187        //Place code here.
图片 188        return values.Count;
图片 189    }
图片 190}
图片 191
图片 192图片 193/**//// <summary>
图片 194/// Article实体类
图片 195/// </summary>
图片 196/// <remarks>
图片 197/// 示例而已,实际项目中要继承自System.Web.Profile.ProfileBase
图片 198/// </remarks>
图片 199public class Article
图片 200图片 201图片 202{
图片 203    private string _title;
图片 204图片 205    /**//// <summary>
图片 206    /// 小说标题
图片 207    /// </summary>
图片 208    public string Title
图片 209图片 210    图片 211{
图片 212图片 213        get 图片 214{ return _title; }
图片 215图片 216        set 图片 217{ _title = value; }
图片 218    }
图片 219
图片 220    private DateTime _publishTime;
图片 221图片 222    /**//// <summary>
图片 223    /// 作品发布日期
图片 224    /// </summary>
图片 225    public DateTime PublishTime
图片 226图片 227    图片 228{
图片 229图片 230        get 图片 231{ return _publishTime; }
图片 232图片 233        set 图片 234{ _publishTime = value; }
图片 235    }
图片 236}
图片 237

在Pageflakes的运行中,我们早就差不多每一日都从客户端得到400个到600个超时错误报告,大家从未发现那是怎么发生的。起头,大家猜疑是网络连接过慢造成的,不过不容许这样多的用户都产生那种场合。后来,我们猜疑是主机提供商的互连网出现了难题。大家做了多量的互连网析去发现标题是或不是是出现在互联网上,不过大家并未发觉别的尤其。大家使用了SQL
Profiler去搜寻是还是不是是长日子运作的询问导致了ASP.NET请求执行时的过期。不过不幸,大家最后发现的是,超过百分之五十过期错误出现的情景都以先有局地坏的调用,然后好的调用也过期了。所以大家修改了Atlas运转时,引进了活动重试的作用,难题到底完全消失了。可是,自动重试供给对ASP.NET
AJAX框架的Javascript做一遍“灵魂口腔科手术”,这些方法会须要每种调用在逾期后都重试一回。为了贯彻它,大家要求截获全数web
method调用并且在onFailure回调函数中作个钩,假诺退步的缘由是晚点,onFailure将再一次调用相同的web
method

Sample.aspx

另一个须要关切的觉察是当我们出门旅行感到困倦时,想透过酒馆或飞机场的有线网络连接到网络访问Pageflakes的时候,第三回访问总是不成功,并且具有的web
service调用在第③遍尝试中一连战败。直到大家刷新在此以前都不会做事。那也是大家要促成web
service调用当下自动重试的另3个重要缘由,它恰恰能够化解这些标题。

图片 238图片 239<%图片 240@ Page Language=”C#” MasterPageFile=”~/Site.master” AutoEventWireup=”true” CodeFile=”Sample.aspx.cs”
图片 241    Inherits=”ClientScripting_SysServices_山姆ple” Title=”Sys.瑟维斯s命名空间下的类” %>
图片 242
图片 243<asp:Content ID=”Content1″ ContentPlaceHolderID=”ContentPlaceHolder1″ runat=”Server”>
图片 244    <div>
图片 245        帐号:<input type=”text” id=”txtUserId” /></div>
图片 246    <div>
图片 247        密码:<input type=”password” id=”txtPassword” /></div>
图片 248    <div>
图片 249         </div>
图片 250    <div>
图片 251        <input type=”button” id=”btnLogin” value=”登录” onclick=”btnLogin_click()” />
图片 252        <input type=”button” id=”btnLogout” value=”注销” onclick=”btnLogout_click()” /></div>
图片 253    <div>
图片 254         </div>
图片 255    <div>
图片 256        年龄:<input type=”text” id=”txtAge” /></div>
图片 257    <div>
图片 258        薪水:<input type=”text” id=”txtSalary” /></div>
图片 259    <div>
图片 260        <input type=”button” id=”btnSave” value=”保存Profile” onclick=”btnSave_click()” />
图片 261        <input type=”button” id=”btnLoad” value=”读取Profile” onclick=”btnLoad_click()” />
图片 262    </div>
图片 263    <div>
图片 264         </div>
图片 265    <div id=”result” />
图片 266
图片 267图片 268    <script type=”text/javascript”>图片 269
图片 270        var userId;
图片 271        var password;
图片 272        var login;
图片 273        var logout;
图片 274        var age;
图片 275        var salary
图片 276
图片 277        function pageLoad()
图片 278图片 279        图片 280{
图片 281            userId = $get(“txtUserId”);
图片 282            password = $get(“txtPassword”);
图片 283            login = $get(“btnLogin”);
图片 284            logout = $get(“btnLogout”);
图片 285            age = $get(“txtAge”);
图片 286            salary = $get(“txtSalary”);
图片 287            
图片 288            // path – authentication service路径
图片 289            $get(“result”).innerHTML = “AuthenticationService path:” + Sys.Services.AuthenticationService.get_path() + “<br />”;
图片 290            // timeout – 超时时间
图片 291            $get(“result”).innerHTML += “AuthenticationService timeout:” + Sys.Services.AuthenticationService.get_timeout() + “<br />”;
图片 292            // path – profile service路径
图片 293            $get(“result”).innerHTML += “ProfileService path:” + Sys.Services.ProfileService.get_path() + “<br />”;
图片 294            // timeout – 超时时间
图片 295            $get(“result”).innerHTML += “ProfileService timeout:” + Sys.Services.ProfileService.get_timeout() + “<br />”;
图片 296        }       
图片 297                
图片 298        function btnLogin_click()
图片 299图片 300        图片 301{
图片 302            // defaultLoginCompletedCallback – 登录成功后的回调函数
图片 303            Sys.Services.AuthenticationService.set_defaultLoginCompletedCallback(onLoginCompleted);
图片 304            // defaultFailedCallback – 登录或注销失利后的回调函数
图片 305            Sys.Services.AuthenticationService.set_defaultFailedCallback(onFailed);
图片 306            
图片 307            Sys.Services.AuthenticationService.login
图片 308            (
图片 309                userId.value, // 用户名
图片 310                password.value, // 密码
图片 311                false, // 是不是跨浏览器保存认证音讯(持久保留)
图片 312                null, // 保留字段,也许在以后使用
图片 313                null, // 登录成功后重定向到的USportageL
图片 314                null, // 登录成功后的回调函数
图片 315                null, // 登录失败后的回调函数
图片 316                “用户上下文” // 用户上下文
图片 317            );
图片 318        }
图片 319        
图片 320        function btnLogout_click()
图片 321图片 322        图片 323{
图片 324            // defaultLogoutCompletedCallback – 注销成功后的回调函数
图片 325            Sys.Services.AuthenticationService.set_defaultLogoutCompletedCallback(onLogoutCompleted);
图片 326            // defaultFailedCallback – 登录或吊销失利后的回调函数
图片 327            Sys.Services.AuthenticationService.set_defaultFailedCallback(onFailed);
图片 328
图片 329            Sys.Services.AuthenticationService.logout
图片 330            (
图片 331                null, // 注销成功后重定向到的UCRUISERL
图片 332                null, // 注销成功后的回调函数
图片 333                null, // 注销失利后的回调函数
图片 334                null // 用户上下文
图片 335            );
图片 336        }
图片 337        
图片 338        function onLoginCompleted(validCredentials, userContext, methodName)
图片 339图片 340        图片 341{
图片 342            password.value = “”;
图片 343            
图片 344            // validCredentials – 是或不是中标通过了验证
图片 345            // userContext – 用户上下文
图片 346            // methodName – 调用的章程名
图片 347            if (validCredentials) 
图片 348图片 349            图片 350{
图片 351                userId.value = “”;
图片 352                
图片 353                $get(“result”).innerHTML = “登录成功” + “<br />”;
图片 354                $get(“result”).innerHTML += “用户上下文:” + userContext + “<br />”;
图片 355                $get(“result”).innerHTML += “调用的不二法门名为:” + methodName + “<br />”;
图片 356            }
图片 357            else
图片 358图片 359            图片 360{
图片 361                $get(“result”).innerHTML = “登录战败” + “<br />”;
图片 362            }
图片 363            
图片 364            // isLoggedIn – 当前用户是还是不是曾经报到
图片 365            var status = Sys.Services.AuthenticationService.get_isLoggedIn();
图片 366            $get(“result”).innerHTML += “登录景况:” + status + “<br />”;
图片 367        }
图片 368        
图片 369        function onFailed(error, userContext, methodName)
图片 370图片 371        图片 372{    
图片 373            // error – Sys.Net.WebServiceError对象
图片 374            // userContext – 用户上下文
图片 375            // methodName – 调用的法门名
图片 376            $get(“result”).innerHTML += “错误音讯:” + error.get_message() + “<br />”;
图片 377        }
图片 378        
图片 379        function onLogoutCompleted(result, userContext, methodName) 
图片 380图片 381        图片 382{
图片 383            // result – 保留字段,恐怕在现在使用,始终为null
图片 384            // userContext – 用户上下文
图片 385            // methodName – 调用的法门名
图片 386            alert(“成功调用” + methodName) + “<br />”;
图片 387        }
图片 388        
图片 389        
图片 390        function btnLoad_click()
图片 391图片 392        图片 393{
图片 394            // defaultLoadCompletedCallback – 读取Profile成功后的回调函数
图片 395            Sys.Services.ProfileService.set_defaultLoadCompletedCallback(onLoadCompleted);
图片 396            // defaultFailedCallback – 读取或保存Profile失败后的回调函数
图片 397            Sys.Services.ProfileService.set_defaultFailedCallback(onFailed);
图片 398            
图片 399            Sys.Services.ProfileService.load
图片 400            (
图片 401                null, // Profile属性名称数组
图片 402                null, // 成功后的回调函数
图片 403                null, // 战败后的回调函数
图片 404                null // 用户上下文
图片 405            );
图片 406        }
图片 407        
图片 408        function btnSave_click()
图片 409图片 410        图片 411{
图片 412            // defaultSaveCompletedCallback – 保存Profile成功后的回调函数
图片 413            Sys.Services.ProfileService.set_defaultSaveCompletedCallback(onSaveCompleted);
图片 414            // defaultFailedCallback – 读取或保存Profile失利后的回调函数
图片 415            Sys.Services.ProfileService.set_defaultFailedCallback(onFailed);
图片 416            
图片 417            Sys.Services.ProfileService.properties.Age = age.value;
图片 418            Sys.Services.ProfileService.properties.Salary = salary.value;
图片 419            
图片 420            // 定义一个Profile组(同时须要在Web.config中定义)
图片 421            Sys.Services.ProfileService.properties.Article = new Sys.Services.ProfileGroup();
图片 422            Sys.Services.ProfileService.properties.Article.Title = “Article Title”;
图片 423            Sys.Services.ProfileService.properties.Article.PublishTime = new Date();
图片 424
图片 425            Sys.Services.ProfileService.save
图片 426            (
图片 427                null, // Profile属性名称数组
图片 428                null, // 成功后的回调函数
图片 429                null, // 失败后的回调函数
图片 430                null // 用户上下文
图片 431            );
图片 432        }
图片 433        
图片 434        function onLoadCompleted(numProperties, userContext, methodName)
图片 435图片 436        图片 437{
图片 438            // numProperties – 重返的Profile属性个数
图片 439            // userContext – 用户上下文
图片 440            // methodName – 调用的艺术名
图片 441            $get(“result”).innerHTML = “通过Profile读取的习性的数码为:” + numProperties.toString() + “<br />”;
图片 442            $get(“result”).innerHTML += “Age:” + Sys.Services.ProfileService.properties.Age + “<br />”;
图片 443            $get(“result”).innerHTML += “Article Title:” + Sys.Services.ProfileService.properties.Article.Title + “<br />”;    
图片 444            $get(“result”).innerHTML += “Article PublishTime:” + Sys.Services.ProfileService.properties.Article.PublishTime.format(“yyyy-MM-dd”) + “<br />”;
图片 445        }
图片 446
图片 447        function onSaveCompleted(numProperties, userContext, methodName)
图片 448图片 449        图片 450{
图片 451            // numProperties – 保存的Profile属性个数
图片 452            // userContext – 用户上下文
图片 453            // methodName – 调用的情势名
图片 454            $get(“result”).innerHTML = “通过Profile保存的质量的数目为:” + numProperties.toString() + “<br />”;
图片 455        }
图片 456    </script>
图片 457
图片 458</asp:Content>
图片 459

此处小编会告诉您如何是好。Sys$Net$WebServiceProxy$invoke函数是肩负处理全数web
service调用的。所以,大家需求经过两个自定义onFailure回调函数来替换那一个函数。只要有错误恐怕逾期就会刺激这一个自定义回调函数。所以,当有逾期发生的时候,就会重复调用那一个函数,重试就会发出。

ScriptManager的设置

图片 460Sys.Net.WebServiceProxy.retryOnFailure = 
图片 461    function(result, userContext, methodName, retryParams, onFailure)
图片 462图片 463图片 464{
图片 465    if( result.get_timedOut() )
图片 466图片 467    图片 468{
图片 469        if( typeof retryParams != “undefined” )
图片 470图片 471        图片 472{
图片 473            debug.trace(“Retry: ” + methodName);
图片 474            Sys.Net.WebServiceProxy.original_invoke.apply(this, retryParams );
图片 475        }
图片 476        else
图片 477图片 478        图片 479{
图片 480            if( onFailure ) onFailure(result, userContext, methodName);
图片 481        }
图片 482    }
图片 483    else
图片 484图片 485    图片 486{
图片 487        if( onFailure ) onFailure(result, userContext, methodName);
图片 488    }
图片 489}
图片 490
图片 491Sys.Net.WebServiceProxy.original_invoke = Sys.Net.WebServiceProxy.invoke;
图片 492Sys.Net.WebServiceProxy.invoke = 
图片 493    function Sys$Net$WebServiceProxy$invoke(servicePath, methodName, useGet, 
图片 494        params, onSuccess, onFailure, userContext, timeout)
图片 495图片 496图片 497{   
图片 498    var retryParams = [ servicePath, methodName, useGet, params, 
图片 499        onSuccess, onFailure, userContext, timeout ];
图片 500    
图片 501    // 起始调用失败
图片 502    // 处理自动重试
图片 503    var newOnFailure = Function.createDelegate( this, 
图片 504        function(result, userContext, methodName) 
图片 505图片 506        图片 507
图片 508            Sys.Net.WebServiceProxy.retryOnFailure(result, userContext, 
图片 509                methodName, retryParams, onFailure); 
图片 510        } );
图片 511        
图片 512    Sys.Net.WebServiceProxy.original_invoke(servicePath, methodName, useGet, 
图片 513        params, onSuccess, newOnFailure, userContext, timeout);
图片 514}

图片 515        <asp:ScriptManager ID=”ScriptManager1″ runat=”server”>
图片 516            <AuthenticationService Path=”~/ClientScripting/SysServices/AuthenticationService.asmx” />
图片 517            <ProfileService Path=”~/ClientScripting/SysServices/ProfileService.asmx” />
图片 518        </asp:ScriptManager>
图片 519

运作的时候,它将把每一种超时调用都重试一回
图片 520

Web.config中的相关安装(在<system.web />节点下)

此地你可以看出第一个方式成功了,全体别的超时的调用都会被重试。而且你也会看到重试一遍后的调用都事业有成了。发生那种情形是因为在重试中服务端的主意不会做超时处理。所以,那注明了我们的达成情势是毋庸置疑的。

图片 521    <profile enabled=”true”>
图片 522      <properties>
图片 523        <group name=”Article”>
图片 524          <add name=”Title” type=”System.String” />
图片 525          <add name=”PublishTime” type=”System.DateTime” />
图片 526        </group>
图片 527      </properties>
图片 528    </profile>
图片 529

浏览器只同意同暂时间内有多少个调用,此时不会执行别的任何命令
浏览器在同最近间内只好对一个域名处理八个冒出的AJAX调用。尽管您有多少个AJAX调用,那么浏览器首先将会处理五个,然后等内部1个完了后,再处理另三个调用,直到剩余的多少个调用都被成功。其它,你不要期待调用的实施各类会与您处理调用的逐条相同,那是怎么呢?
图片 530

运维结果
一 、页面加载后
AuthenticationService
path:/Web/ClientScripting/SysServices/AuthenticationService.asmx
AuthenticationService timeout:0
ProfileService path:ProfileService.asmx
ProfileService timeout:0

正如你所见,调用3索要下载相比大的数码,所以它所需的时日就会比调用5要长,事实上,调用5会在调用3此前实施完。

2、单击“登录”按钮
签到成功
用户上下文:用户上下文
调用的方式名为:Sys.Services.AuthenticationService.login
签到情状:true

故此,在HTTP的社会风气里,那个都以不可预见的。

3、单击“注销”按钮
弹出框,音信:成功调用Sys.Services.AuthenticationService.logout

当队列里有多于多少个调用的时候浏览器将不会响应
品尝那样做,在首次访问时打开任何八个加载了大气奇骏SS的页(如Pageflakes,
Netvibes,
Protopage),在加载时期,你能够尝试着单击3个链接到另三个站点如故试着一向访问另多个站点,那么你就会意识浏览器不会有别的响应。直到浏览器里具有队列的AJAX调用都形成之后,浏览器才能经受另三个平移。那是IE的3个比较不好的地点,不过Firefox和Opera就不会有此难题。

4、单击“保存Profile”按钮
透过Profile保存的品质的数目为:4

这一个题目是,当您有大气的AJAX调用的时候,浏览器会将持有的调用放到二个行列里,在同权且间内只进行在那之中的八个。所以,要是你单击了有个别链接可能转载另四个站点,那么浏览器必须等待在取得另二个调用在此以前正在推行的调用实现以往才会去处理。化解这几个题材的办法正是防患浏览器在同一时间内有多于七个的调用在队列里。大家供给有限支持七个谈得来的行列,然后从我们的行列里将多少个贰个调用的发到浏览器的类别中。

5、单击“读取Profile”按钮
透过Profile读取的质量的多寡为:3
Age:27
Article Title:Article Title From Server
Article PublishTime:2007-07-12

其一消除方案是很棒,它能够防患调用间的争辨:

OK [源码下载]

图片 531图片 532var GlobalCallQueue = 图片 533{
图片 534    _callQueue : [],    // 保存web method的调用列表
图片 535    _callInProgress : 0,    // 浏览器方今处理的web method的号子
图片 536    _maxConcurrentCall : 2, // 同近来间内进行调用的最大数
图片 537    _delayBetweenCalls : 50, // 调用执行之间的推移
图片 538    call : function(servicePath, methodName, useGet, 
图片 539        params, onSuccess, onFailure, userContext, timeout)
图片 540图片 541    图片 542{
图片 543        var queuedCall = new QueuedCall(servicePath, methodName, useGet, 
图片 544            params, onSuccess, onFailure, userContext, timeout);
图片 545
图片 546        Array.add(GlobalCallQueue._callQueue,queuedCall);
图片 547        GlobalCallQueue.run();
图片 548    },
图片 549    run : function()
图片 550图片 551    图片 552{
图片 553        /// 从队列里推行1个调用
图片 554        
图片 555        if( 0 == GlobalCallQueue._callQueue.length ) return;
图片 556        if( GlobalCallQueue._callInProgress < 
图片 557            GlobalCallQueue._maxConcurrentCall )
图片 558图片 559        图片 560{
图片 561            GlobalCallQueue._callInProgress ++;
图片 562            // 获得第一个调用队列
图片 563            var queuedCall = GlobalCallQueue._callQueue[0];
图片 564            Array.removeAt( GlobalCallQueue._callQueue, 0 );
图片 565            
图片 566            // 调用web method
图片 567            queuedCall.execute();
图片 568        }
图片 569        else
图片 570图片 571        图片 572{
图片 573            // 达到最大并发数,不可能运作另1个调用
图片 574    // 处理中的webservice method
图片 575        }
图片 576    },
图片 577    callComplete : function()
图片 578图片 579    图片 580{
图片 581        GlobalCallQueue._callInProgress –;
图片 582        GlobalCallQueue.run();
图片 583    }
图片 584};
图片 585
图片 586QueuedCall = function( servicePath, methodName, useGet, params, 
图片 587    onSuccess, onFailure, userContext, timeout )
图片 588图片 589图片 590{
图片 591    this._servicePath = servicePath;
图片 592    this._methodName = methodName;
图片 593    this._useGet = useGet;
图片 594    this._params = params;
图片 595    
图片 596    this._onSuccess = onSuccess;
图片 597    this._onFailure = onFailure;
图片 598    this._userContext = userContext;
图片 599    this._timeout = timeout;
图片 600}
图片 601
图片 602QueuedCall.prototype = 
图片 603图片 604图片 605{
图片 606    execute : function()
图片 607图片 608    图片 609{
图片 610        Sys.Net.WebServiceProxy.original_invoke( 
图片 611            this._servicePath, this._methodName, this._useGet, this._params,  
图片 612            Function.createDelegate(this, this.onSuccess), // 调用处理完了
图片 613            Function.createDelegate(this, this.onFailure), // 调用处理完了
图片 614            this._userContext, this._timeout );
图片 615    },
图片 616    onSuccess : function(result, userContext, methodName)
图片 617图片 618    图片 619{
图片 620        this._onSuccess(result, userContext, methodName);
图片 621        GlobalCallQueue.callComplete();            
图片 622    },        
图片 623    onFailure : function(result, userContext, methodName)
图片 624图片 625    图片 626{
图片 627        this._onFailure(result, userContext, methodName);
图片 628        GlobalCallQueue.callComplete();            
图片 629    }        
图片 630};

QueueCall封装了二个web
method调用,它具备真正web服务调用的兼具参数,并且重写了onSuccess和onFailure回调函数。大家想知道当二个调用完结或许失利了的时候,如何从我们的行列里调出另一个调用。GlobalCallQueue保存了web服务调用的列表。无论何时,当三个web
method被调用时,我们先要对GlobalCallQueue中的调用实行排队,并从大家自身的队列里四个四个的施行调用。那样就能够有限支撑浏览器在同等的大运里不会有多于多少个的调用,所以浏览器就不会停下响应。

为了保险队列是依据调用的,大家需求像在此之前那么再度重写ASP.NET AJAX的web
method

图片 631Sys.Net.WebServiceProxy.original_invoke = Sys.Net.WebServiceProxy.invoke;
图片 632Sys.Net.WebServiceProxy.invoke = 
图片 633    function Sys$Net$WebServiceProxy$invoke(servicePath, methodName, 
图片 634        useGet, params, onSuccess, onFailure, userContext, timeout)
图片 635图片 636图片 637{   
图片 638    GlobalCallQueue.call(servicePath, methodName, useGet, params, 
图片 639        onSuccess, onFailure, userContext, timeout);
图片 640}

在浏览器中缓存web服务响应得以鲜明节省带宽
浏览器能够在用户的硬盘里缓存图片、JavaScript、CSS文件,假设XML
HTTP调用是2个HTTP
GET的话也是足以缓存的。那么些缓存是基于U凯雷德L的。假若是一模一样U奥德赛L,且保存在同四个计算机里,那么数量将从缓存里加载,而不会向服务器再一次伸手。基本上,浏览器能够缓存任何HTTP
GET请求并且重临基于ULX570L的被缓存数据。假设您把一个XML HTTP调用作为HTTP
Get格局的话,那么服务端将回到一些新鲜的头音信,用于文告浏览器对相应做缓存,之后再一次调用相同的始末,结果就会应声从缓存中被重临,从而收缩了网络传输延迟和下载时间。

在Pageflakes中,我们对用户的情状做了缓存,所以当用户再度访问的时候会从浏览器的缓存里立马收获缓存数据,而不用经过服务端。因而第二遍加载时间会变得一点也十分的快。大家也缓存了用户的一些行为所发生的结果。当用户再一次做一样行为时,缓存结果就会即刻从用户的本土缓存中加载,从而减少了网络传输时间。用户会体会到3个快捷加载和高响应的站点,获得速度会有综上可得增加。

本条点子正是处理Atlas web service调用时要使用HTTP
GET方式,并且要赶回一些强烈的HTTP头音信报告浏览器具体要缓存多久。尽管在响应期间你回来了三个“Expires”头音讯,那么浏览器就会缓存这一个XML
HTTP结果。那里您要求再次来到五个头音信去通告浏览器缓存结果。

图片 641HTTP/1.1 200 OK 
图片 642Expires: Fri, 1 Jan 2030 
图片 643Cache-Control: public

该新闻将通知浏览器要缓存结果直到2030年10月二五日。在你处理具有同样参数的同3个XML
HTTP调用的时候,就将从总结机的缓存中加载数据,而不会由此服务端。那里还有愈多的主宰缓存的高档方法。例如,有一个头新闻通报浏览器缓存60秒,那么浏览器要在60秒今后才能接触到服务端并获得新的结果。当60秒后浏览器本地缓存过期的时候,它也会幸免从代理服务器端得到已缓存的响应。

图片 644HTTP/1.1 200 OK 
图片 645Cache-Control: private, must-revalidate, proxy-revalidate, max-age=60

让我们来尝试着在二个ASP.NET web service方法中爆发如此的头消息:

图片 646[WebMethod][ScriptMethod(UseHttpGet=true)]
图片 647public string CachedGet()
图片 648图片 649图片 650{
图片 651    TimeSpan cacheDuration = TimeSpan.FromMinutes(1);
图片 652    Context.Response.Cache.SetCacheability(HttpCacheability.Public);
图片 653    Context.Response.Cache.SetExpires(DateTime.Now.Add(cacheDuration));
图片 654    Context.Response.Cache.SetMaxAge(cacheDuration);
图片 655    Context.Response.Cache.AppendCacheExtension(
图片 656           “must-revalidate, proxy-revalidate”);
图片 657
图片 658    return DateTime.Now.ToString();
图片 659}

结果就是下列头消息:
图片 660

“Expires”头音讯被科学的装置。不过难点产生在“Cache-Control”,它显得了“max-age”的值被设置成零,那将堵住浏览器从其它缓存中读取数据。假使您真的想禁止使用缓存,当然要发送这样一条Cache-Control头音信。结果像是产生了反而的业务。

出口的结果依旧是错的,并从未被缓存
图片 661

不可能改变“max-age”头新闻是ASP.NET
2.0中的bug。因为“max-age”被设置成零,而“max-age”的值等于零就象征不供给缓存,所以ASP.NET
2.0才把“Cache-Control”设置为“private”。所以使ASP.NET
2.0回来正确的缓存响应的头消息是不可行的。

简短节说。反编写翻译HttpCachePolicy类(Context.Response.Cache对象的类)之后,笔者意识了之类代码:
图片 662

不知缘何,this._maxAge的值会被设置成零,看一下那段代码“if
(!this._isMaxAgeSet || (delta <
this._maxAge))”,它用来幸免_maxAge被安装得过大。由于这几个标题,大家需绕过Set马克斯Age函数,然后接纳反射去一贯的安装_maxAge的值。

图片 663[WebMethod][ScriptMethod(UseHttpGet=true)]
图片 664public string CachedGet2()
图片 665图片 666图片 667{
图片 668    TimeSpan cacheDuration = TimeSpan.FromMinutes(1);
图片 669
图片 670    FieldInfo maxAge = Context.Response.Cache.GetType().GetField(“_maxAge”, 
图片 671        BindingFlags.Instance|BindingFlags.NonPublic);
图片 672    maxAge.SetValue(Context.Response.Cache, cacheDuration);
图片 673
图片 674    Context.Response.Cache.SetCacheability(HttpCacheability.Public);
图片 675    Context.Response.Cache.SetExpires(DateTime.Now.Add(cacheDuration));
图片 676    Context.Response.Cache.AppendCacheExtension(
图片 677            “must-revalidate, proxy-revalidate”);
图片 678
图片 679    return DateTime.Now.ToString();
图片 680}

它将再次来到下列头新闻:
图片 681

今后“max-age”被设置成了60,所以浏览器将把多少缓存60秒。假如60秒内你采用了千篇一律的调用,那么它将回到相同的结果。下边是一个展现从服务端重返日期的出口结果:
图片 682

1分钟后,缓存过期并且浏览器再一次向服务器发送三个请求。客户端代码如下:

图片 683function testCache()
图片 684图片 685图片 686{
图片 687    TestService.CachedGet(function(result)
图片 688图片 689    图片 690{
图片 691        debug.trace(result);
图片 692    });
图片 693}

此处还有另二个标题亟需消除。在web.config文件中,你晤面到ASP.NET
AJAX扩张了上面那一个因素:

图片 694<system.web>
图片 695        <trust level=”Medium”/>

它会幸免大家设置响应对象的_maxAge,因为它需求反射。所以你必须删除trust成分或许设置它的level属性为Full

图片 696<system.web> 
图片 697    <trust level=”Full”/>

当“this”不是你觉得的“this”的时候
Atlas回调函数不会在它们被调用的等同上下文中执行
。例如,假若您在二个JavaScript类里像这么使用三个web method

图片 698function SampleClass()
图片 699图片 700图片 701{
图片 702    this.id = 1;
图片 703    this.call = function()
图片 704图片 705    图片 706{
图片 707        TestService.DoSomething( “Hi”, function(result)
图片 708图片 709        图片 710{
图片 711            debug.dump( this.id );
图片 712        } );
图片 713    }
图片 714}

当您调用“call”方法的时候会时有产生哪些?你会在debug中赢得“1”吗?不会,你将在debug中获取“null”,因为那么些“this”不再是类的实例。那是每一位常常会犯的一无所长。那在Atlas的文书档案里照样没有有关认证,笔者意识许多开发职员都开销时间去寻觅那是怎样错误。

由来是那般的。大家清楚假使JavaScript事件被触发,那么“this”就是指引致事件时有爆发的十三分HTML成分,所以即便你像上面那样写的话:

图片 715function SampleClass()
图片 716图片 717图片 718{
图片 719    this.id = 1;
图片 720    this.call = function()
图片 721图片 722    图片 723{
图片 724        TestService.DoSomething( “Hi”, function(result)
图片 725图片 726        图片 727{
图片 728            debug.dump( this.id );
图片 729        } );
图片 730    }
图片 731}
图片 732
图片 733<input type=”button” id=”ButtonID” onclick=”o.onclick” />

比方您单击了这么些按钮,就会发觉“ButtonID”代替了“1”。原因就是其一按钮正在调用“call”方法。所以,那个调用在按钮对象的上下文中成就,而“this”就被映射为那么些按钮对象。

一律的,当XML
HTTP触发了足以捕获和刺激回调函数的onreadystatechanged事件的时候,代码执行仍旧在XML
HTTP的前后文中。它是触发了那些事件的XML
HTTP对象。结果,“this”就针对了XML
HTTP对象,而不是您协调的在回调函数被声明处的类。

为了使回调函数在类的实例的左右文中激发,所以要让“this”指向类的实例,你须求做如下改变。

图片 734function SampleClass()
图片 735图片 736图片 737{
图片 738    this.id = 1;
图片 739    this.call = function()
图片 740图片 741    图片 742{
图片 743        TestService.DoSomething( “Hi”, 
图片 744            Function.createDelegate( this, function(result)
图片 745图片 746        图片 747{
图片 748            debug.dump( this.id );
图片 749        } ) );
图片 750    }
图片 751}

此间的Function.createDelegate用来创制二个调用“this”上下文下的一定函数的嘱托。它可以给函数提供“this”的上下文。Function.createDelegate被定义在Atlas运转时。

图片 752图片 753Function.createDelegate = function(instance, method) 图片 754{
图片 755图片 756    return function() 图片 757{
图片 758        return method.apply(instance, arguments);
图片 759    }
图片 760}

HTTP POST要比HTTP GET慢,可是ASP.NET AJAX暗中认可用的是HTTP POST
默许情状下,ASP.NET AJAX的持有web service调用都利用HTTP POST情势。HTTP
POST格局要比HTTP
GET情势交给愈来愈多的代价,它通过互联网传输更加多的字节,因而就要占用宝贵的互连网传输时间,也使得ASP.NET要在服务端做一些极度处理。所以,在大概的事态下你应有运用HTTP
GET格局。不过,HTTP
GET格局不容许你将对象作为参数字传送输,你不得不传输数字、字符串和日期。当你处理1个HTTP
GET调用的时候,Atlas会组织3个被编码的UGL450L并运用它。所以,你不应当传输很多剧情而使U途胜L超越2050个字符。据本身眼下所知,这是其余U昂科雷L的最大尺寸。

为了在一个web service方法中央银行使HTTP
GET方式,你须要用[ScriptMethod(UseHttpGet=true)]品质修饰这几个方法:

图片 761[WebMethod] [ScriptMethod(UseHttpGet=true)] 
图片 762public string HelloWorld()
图片 763图片 764图片 765{
图片 766}

POST与GET的另1个题材是,POST须要三次互连网传输。当你选拔POST的时候,web服务器会头阵送三个“HTTP
100
Continue”,那意味着web服务器已经准备好了收取内容。之后,浏览器才会发送实际数目。所以,因为POST请求的启幕阶段要比GET格局开支越来越多的时间,在AJAX程序里网络延迟(你的总括机和服务器之间的数额传输)是要授予丰富尊敬的,因为AJAX适合处理部分小的内需在毫秒级的日子内形成的调用。否则程序会不流畅并且让用户认为厌烦。

Ethereal是2个很好的工具,它能够侦测到POST和GET的情况下到底发生了怎么:
图片 767

从下面的图中,你能够看看POST方式在备选发送实际数据在此以前,要从web服务器请求一段“HTTP
100
Continue”的承认新闻,那事后才会传输数据。另一方面,GET格局传输数据是不须求别的确认的。

从而,当你要从服务端下载页的某一有的、3个表格也许是一段文本之类的时候就活该利用HTTP
GET形式。而假诺要像web
form那样以提交的格局发送数据到服务端的话就不应该接纳HTTP GET格局。

结论
地点所说的这一个高级技术都已经在Pageflakes中达成了,那里本人并没有提及它的事无巨细完结格局,不过原理都提到了,所以,你能够放心地行使那一个技术。这一个技能将节省你化解难题的光阴,或者在开发条件中你向来没认识到这一个题材,不过当您科普陈设网站随后,来自世界各州的访问者就将面对这几个题材。一开头就天经地义的落到实处这一个技能将会大大节省你的开销和客户辅助的小时。请同时关注自个儿的博客以博取越来越多的技术。