在ASP.NET中使用AJAX.NET (转译自MSDN)(二)

题记:本想译完这篇来自 Bipin Joshi  的文章,但发现第二篇关于AJAX的文章有些过于简单,于是我想把MSDN上的一篇最新的关于AJAX的文章译过来,以供大家参考!由于这篇文章有很多地方,在上篇文章中已经阐述,所以就按自己的想法,译下了这篇文章。


在这篇文章当中,在使用AJAX时,有了不同的方式,而这种方式更宜于。NET时代的编程人员的理解和运用。本文中提到了AJAX。NET的概念,这是对AJAX的升级应用,简化了使用程序,使用编程效率大大提高。

AJAX.ET
AJAX.NET文档,网站的开发者做了一个很不错的工作,它可以让我们很容易应用和开发自己的WEB程序。在谈到具体的例子之前,我们先要简要介绍一下关于这项技术的一些核心知识。

首先,从AJAX.NET project Web site下载AJAX文件,然后,在你的IIS中建立一个工程(VB。NET或是C#都可以),再添加AJAX。DLL文件的引用。接下来要做的只是简单的配置一下你的WEB。CONFIG文件中的《SYSTEM。WEB》节点。

None.gif < configuration >     
None.gif 
< system.web >   
None.gif  
< httpHandlers >
None.gif   

None.gif   
< add verb = " POST,GET "  path = " ajax/*.ashx "  
None.gif        type
= " Ajax.PageHandlerFactory, Ajax "   />
None.gif  
httpHandlers >   
None.gif  dot.gif
None.gif  dot.gif 
None.gif 
system.web >
None.gif
configuration >
None.gif

为了让服务器端方法可以通过JS来调用,我们需要做二件事情。第一,这个方法必须用 Ajax.AjaxMethodAttribute来声明。第二,在页面的LOAD事件中,我们必须使这个方法注册为通过Ajax.Utility.RegisterTypeForAjax来调用。不用担心,听起来挺复杂的,但是在你的代码当中只要加入几行额外的代码,让我们看实现代码:
//C#
None.gif public   class  Sample : System.Web.UI.Page
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
private void Page_Load(object sender, System.EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif  
//Register the class containing the server-side function
InBlock.gif  
//we are interested in
InBlock.gif
  Ajax.Utility.RegisterTypeForAjax(typeof(Sample));
ExpandedSubBlockEnd.gif }

InBlock.gif [Ajax.AjaxMethod()]
InBlock.gif 
public string GetMessageOfTheDay()
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif  
return "Experience is the mother of wisdom";
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}
VB.NET
ExpandedBlockStart.gif ContractedBlock.gif Public   Class Sample Class Sample
InBlock.gif 
Inherits System.Web.UI.Page
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif 
Private Sub Page_Load()Sub Page_Load(sender AsObject, e As EventArgs) 
InBlock.gif                                         
Handles MyBase.Load
InBlock.gif  
'Register the class containing the server-side function
InBlock.gif
  'we are interested in
InBlock.gif
  Ajax.Utility.RegisterTypeForAjax(GetType(Sample))
ExpandedSubBlockEnd.gif 
End Sub

InBlock.gif 
<Ajax.AjaxMethod()> _
ExpandedSubBlockStart.gifContractedSubBlock.gif 
Public Function GetMessageOfTheDay()Function GetMessageOfTheDay() As String
InBlock.gif  
Return "Experience is the mother of wisdom"
ExpandedSubBlockEnd.gif 
End Function

ExpandedBlockEnd.gif
End Class

None.gif

在下面的例子当中,我们先讲一个AJAX。NET的一个SAMPLE类的友元方法。这个过程发生在相同类的相同页面中,但是,它可以是任何。NET类,或是任何在。NET类中用AjaxMethodAttribute进行申明的类这就有一个简单的类方法:GetMessageOfTheDay。

接下来,我们只要做的是,在JS中应用这些方法。AJAX。NET自动生成一个被注册的SAMPLE类,该类中有一个名字和AJAXMETHOD方法一样的(在此是GetMessageOfTheDay)如下所示:

 
 
None.gif < script language = " javascript " >
None.gif Sample.GetMessageOfTheDay(GetMessageOfTheDay_CallBack);
None.gif 
function  GetMessageOfTheDay_CallBack(response)
ExpandedBlockStart.gifContractedBlock.gif 
dot.gif {
InBlock.gif  alert(response.value);
ExpandedBlockEnd.gif }

None.gif
script >





在JS中的GetMessageOfTheDay方法需要与服务器端方法相同的参数(在这没有参数),此外,JS中的callback
方法,执行并传递response,直到结束。在这,我们可以看到异步的AJAX工作的实质,因为 GetMessageOfTheDay
法的调用并没妨碍JS中其它的操作,也没有妨碍页面中用户的继续操作。当服务器端执行完毕,AJAX。NET
GetMessageOfTheDay_CallBack方法,并传递来自服务器端的结果集。服务器和JS,看起来有些模糊,难以
理解,下面的图例可以帮你很好的了解这一复杂的过程。
ajaxspiced_fig01.gif
还有很多AJAX。NET的有趣之处,比如,它扶持很多。NET的类型,还可以返回很多种不同的值类型,如:XML,DATASET
等。在下面的实际例子当中,你才能体会它如果帮你创建更智能的WEB应用程序。

   
[注:原文中,下面的例子是一个关于DROPDOWNLIST的级联显示的,在前面提到过,在这就不做描述,相关代码
请参见原文,下面仔细讲解关于文档操作的例子,很有挑战性,千万别走开,会有更精彩的]


      
 例子2:文档锁

      
这个例子中我们将介绍一个文档管理系统,当然如其它的系统一样,我们提供concurrency management(我译作
同步在线编辑管理)。也就是说,我们需要一个解决方法,来处理不同的用户来编辑相同的文档。就此,我们会
产生一个”锁装置“类型,来控制多人操作同一文件的可能。利用AJAX我们会让用户有更愉快的文档管理体验。
首先,我们产生一个用户已经在进行编辑的文档队列,并自动提示用户不能修改。第二,我们要确定当用户离开
当前编辑室模式时,文档不会被一直锁住。为此,在这个指导文档中,我们将跳过与AJAX的执行无关的方描述。
然而在下载文档中,会有详细的说明。
   
首先,当用户试图编辑一个文档时,我们会从此文档得到一个排外锁,如果没有,则把文档加到用户的编辑文档队列中,
并返回首页。这没有什么特别的,只是在我们的代码中添加一些必要的行,下面就是在ONLOAD事件中的例子:

None.gif if  ( ! Page.IsPostBack)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
//should validate user input
InBlock.gif
 Document document = GetDocument(Request.QueryString["id"]);
InBlock.gif 
//We have the document, but can't edit it!
InBlock.gif
 if (!Locker.AcquireLock(document))
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif  
//let's add it to the user's list of docs to watch
InBlock.gif
  User.CurrentUser.AddDocumentToQueue(document.DocumentId);
InBlock.gif  Response.Redirect(
"DocumentList.aspx");
ExpandedSubBlockEnd.gif }

InBlock.gif 
//ok, we have the document and CAN edit it
InBlock.gif 
//dot.gif
ExpandedBlockEnd.gif
}

None.gif



最关键的行是把文档添加到当前用户的队列中,其实是添加到SESSION中去。下面,产生一个用户控件,可以放在
任何页面上,可以通知用户任何可以编辑的文档。这个用户控件仅包含一个AJAX方法,下面是具体的代码:

ExpandedBlockStart.gif ContractedBlock.gif Private   Sub Page_Load() Sub Page_Load(s As Object, e As EventArgs) 
InBlock.gif                                   
Handles MyBase.Load
InBlock.gif Ajax.Utility.RegisterTypeForAjax(
GetType(UnlockNotifier))
ExpandedBlockEnd.gif
End Sub

None.gif
None.gif
' Loops through the queued documents and checks if they're available
None.gif
< Ajax.AjaxMethod() >  _
ExpandedBlockStart.gifContractedBlock.gif
Public   Function GetUnlockedDocuments() Function GetUnlockedDocuments() As DocumentCollection
InBlock.gif 
'Get all the queued document ids belonging to the user
InBlock.gif
 Dim queuedDocument As ArrayList = User.CurrentUser.DocumentQueue
InBlock.gif 
Dim unlocked As DocumentCollection = New DocumentCollection
InBlock.gif
InBlock.gif 
For Each documentId As Integer In queuedDocumentIds
InBlock.gif 
'If the queued document is no longer locked
InBlock.gif
  If Not Locker.IsLocked(documentId) Then
InBlock.gif   unlocked.Add(Document.GetDocumentById(documentId))
InBlock.gif  
End If
InBlock.gif 
Next
InBlock.gif
InBlock.gif 
Return unlockedDocuments
ExpandedBlockEnd.gif
End Function

None.gif


现在我们要做的是在JS中实现请求和处理返回结果,我们会放置一个文档释放信息,如果有,将依据返回结果建
一个动态表格。详细的HTML代码如下:

None.gif < div  id ="notifyBox"  style ="display:none;" >
None.gif 
< b > The following queued documents can now be edited b >
None.gif 
< table  cellpadding ="5"  cellspacing ="0"  
None.gif       border
="0"  style ="border:1px solid #EEE;"  
None.gif       id
="notifyTable" >
None.gif  
table >
None.gif
div >
None.gif

如果没有文档显示的话,我们用一个DIV标签来隐藏该区域(或是该用户列中没有文档),表格用来显示结果
我们将用一个轮流检测系统来查看是否有可用文档,一般来说,这意味着我们要一直调用服务器端方法,用一个
延迟,来显示结果。第一个方法只是在页面加载时才触发,后来的方法会X秒调用一次。

None.gif < script language = " javascript " >
None.gifwindow.setTimeout(
" PollQueue(); " 2000 );
None.gif
// fires every 2 seconds to check if a queued document was released
None.gif//
in a real system with a lot of users, 2 seconds might put too high
None.gif//
a load on the server. We could even check first to see if the user
None.gif//
even has anything queued, but we'll certainly need to do some
None.gif//
performance testing
None.gif
function  PollQueue()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
//UnlockNotifier is the type we registered with Ajax.NET
InBlock.gif
 //GetUnlockedDocuments is a method within that type marked with
InBlock.gif
 //the AjaxMethod attribute
InBlock.gif
 UnlockNotifier.GetUnlockedDocuments(PollQueue_CallBack);
InBlock.gif 
//calls itself every 2 seconds
InBlock.gif
 window.setTimeout("PollQueue();"2000);
ExpandedBlockEnd.gif}

None.gif
script >


余下我们要做的就是处理返回的结果值。首先,检测是否有什么错误没,得到结果值,循环显示文档,自动
生成HTML,这样的话,需要加入下面的行到我们的表格中。

None.gif function  PollQueue_CallBack(response)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
var notifyBox = document.getElementById("notifyBox");
InBlock.gif  
var notifyTable = document.getElementById("notifyTable");
InBlock.gif  
//if we couldn't find our table notification box
InBlock.gif
  if (notifyBox == null || notifyTable == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{
InBlock.gif    
return;
ExpandedSubBlockEnd.gif  }

InBlock.gif  
//if the server-side code threw an exception
InBlock.gif
  if (response.error != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif
InBlock.gif    notifyBox.style.display 
= "none"
InBlock.gif    alert(response.error); 
//we should probably do better than this
InBlock.gif
    return;
ExpandedSubBlockEnd.gif  }
  
InBlock.gif    
InBlock.gif  
var documents = response.value;
InBlock.gif  
//if the response wasn't what we expected    
InBlock.gif
  if (documents == null || typeof(documents) != "object")
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{
InBlock.gif    notifyBox.style.display 
= "none";
InBlock.gif    
return;  
ExpandedSubBlockEnd.gif  }
  
InBlock.gif  
for (var i = 0; i < notifyTable.rows.length; ++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{
InBlock.gif   notifyTable.deleteRow(i);
ExpandedSubBlockEnd.gif  }

InBlock.gif  
for(var i = 0; i < documents.length; ++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{    
InBlock.gif    
var row = notifyTable.insertRow(0);
InBlock.gif    row.className 
= "Row" + i%2;
InBlock.gif    
var cell = row.insertCell(0);
InBlock.gif    cell.innerHTML 
= documents[i].Title;
InBlock.gif    cell 
= row.insertCell(1);
InBlock.gif    
var date = documents[i].Created;
InBlock.gif    cell.innerHTML 
= date.getDay() + "/" + date.getMonth() 
InBlock.gif                     
+ "/" + date.getYear();
InBlock.gif    cell 
= row.insertCell(2);
InBlock.gif    cell.innerHTML 
= "" 
InBlock.gif                     
+ documents[i].DocumentId + "'>edit
";
ExpandedSubBlockEnd.gif  }
 
InBlock.gif  notifyBox.style.display 
= "block"
ExpandedBlockEnd.gif}
在这个系统中,最新颖的特色是,当用户离开或关闭,或是返回页面时,文档会自动解锁。这个功能的实现,是依靠,JS中的两个方法: OnBeforeUnLoad 或是 OnUnload ,打开一个新的弹出窗口,在加载时做一些清理工作,然后自行关闭。然而,如果你的浏览器不支持或阻止了这一窗口,那么就没法处理这些工作,导致文件被永久性锁住。为了解决这个问题,我们通过调用服务器端方法解决它。在编辑页面,加一个锁,添加一些JS代码就OK了。
None.gif < script language = " javascript " >
None.gif
// Makes sure the document is unlocked if the user closes the 
None.gif//
browser or hits the back button
None.gif
window.onbeforeunload  =  ReleaseLock;
ExpandedBlockStart.gifContractedBlock.gif
function  ReleaseLock()  dot.gif {
InBlock.gif Locker.ReleaseDocument(
DocumentID%>);
ExpandedBlockEnd.gif}

None.gif
script>

DOCUMENTID 是在页面类文件中定义的,可以存在SESSION中,再通过服务器端方法 ReleaseDocument. ReleaseDocument 来进行文档解锁。

[译到这,这个例子,就告一段落了,在接下来文章中我将对者的第三个更复杂的例子,就是关于论坛对像搜索的,会是更详细的译述,也随时欢迎来信,共同探讨最新科技]

备注:签于个人水平,文章中难免有错误纰漏这处,敬请原谅!本文章转译自MSDN 不能用于商业用途,如果转载请注明出处

转载于:https://www.cnblogs.com/lgp/archive/2005/10/22/259772.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值