The recent upsurge in Asynchronous JavaScript and XML (AJAX) is entirely due to Google's use of Google Suggest and Google Maps. For ASP. NET, AJAX can be processed on the server without returning data, so that the client (browser) has rich server capabilities. In other words, it provides a framework for Asynchronously assigning and processing requests and server responses. AJAX uses some existing technologies that are not very novel, but the hobby of these technologies (together with AJAX) has suddenly heated up.
Please try Michael Schwarz's AJAX. NET Package, through which ASP. NET developers can quickly and conveniently deploy pages that are easy to use AJAX functions. It should be noted that this package is in the initial development stage, so it is not completely mature.
How it works-Overview
AJAX relies on the broker to assign and process requests to and from the server. The. NET package depends on the XmlHttpRequest object of the client. Most browsers support XmlHttpRequest objects, which is why they are selected. Because the purpose of the package is to hide the implementation of XmlHttpRequest, we will not discuss it in detail.
The wrapper itself works by marking. NET functions as AJAX methods. After marking, AJAX creates the corresponding JavaScript functions. These functions (like any JavaScript function) can be called on the client using XmlHttpRequest as a proxy. These proxies are then mapped back to the server-side functions.
Complicated? Not complex. Let's look at an example. Suppose there is a. NET function:
Ublic int Add (int firstNumber, int secondNumber)
{
Return firstNumber + secondNumber;
}
The AJAX. NET Package automatically creates a JavaScript function named "Add" with two parameters. When you call this function using JavaScript (on the client), the request is sent to the server and the result is returned to the client.
Initial settings
First, we will introduce the. dll steps used in the "Install" project. Skip this section if you know how to add a. dll file reference.
First, if not, download the latest AJAX version. Decompress the downloaded file and place ajax. dll in the reference folder of the project. In Visual Studio. NET, select the "References" node of the Organic Solution Explorer and Add Reference ). In the displayed dialog box, Click Browse and find the ref/ajax. dll file. Click Open and OK ). In this way, you can program with the AJAX. NET package.
Create HttpHandler
To ensure normal operation, the first step is to set the HttpHandler of the package in web. config. You don't need to explain in detail what HttpHandlers is and how it works, as long as you know that they are used to process ASP. NET requests. For example, all *. aspx page requests are processed by the System. Web. UI. PageHandlerFactory class. Similarly, we make all ajax/*. ashx requests processed by Ajax. PageHandlerFactory:
<Configuration>
<System. web>
<HttpHandlers>
<Add verb = "POST, GET" path = "ajax/*. ashx"
Type = "Ajax. PageHandlerFactory, Ajax"/>
</HttpHandlers>
<System. web>
</Configuration>
In short, the above Code tells ASP. NET that any request matching the specified path (ajax/*. ashx) is processed by Ajax. PageHandlerFactory instead of the default handler factory. You do not need to create an ajax subdirectory. This mysterious directory is used to allow other HttpHandlers to use the. ashx extension in their own subdirectories.
Create page
Now we can start encoding. Create a new page or open an existing page. In the code after file, add the following code for the Page_Load event:
Public class Index: System. Web. UI. Page {
Private void Page_Load (object sender, EventArgs e ){
Ajax. Utility. RegisterTypeForAjax (typeof (Index ));
//
}
//
}
Calling RegisterTypeForAjax will trigger the following JavaScript on the page (or manually Add the following two lines of code to the page ):
<Script language = "javascript" src = "ajax/common. ashx"> </script>
<Script language = "javascript"
Src = "ajax/Namespace. PageClass, AssemblyName. ashx"> </script>
The last line indicates:
Namespace. PageClass -- The Namespace and class of the current Page (usually the value of the Inherits attribute in the @ Page command)
AssemblyName -- Name of the Assembly to which the current page belongs (usually the project name)
The following is an example of the sample. aspx page in the AjaxPlay project:
<% @ Page Inherits = "AjaxPlay. Sample" Codebehind = "sample. aspx. cs" %>
<Html>
<Head>
<Script language = "javascript" src = "ajax/common. ashx"> </script>
<Script language = "javascript"
Src = "ajax/AjaxPlay. Sample, AjaxPlay. ashx"> </script>
</Head>
<Body>
<Form id = "Form1" method = "post" runat = "server">
</Form>
</Body>
</Html>
You can manually navigate to the src path (view the source code, copy and paste the path) in the browser to check whether everything is normal. If both paths output meaningless texts, everything would be fine. If nothing is output or an ASP. NET error occurs, it indicates that there are some problems.
Even if you don't know how HttpHandlers works, the above example is easy to understand. Through web. config, we have ensured that all ajax/*. ashx requests are processed by custom handlers. Obviously, the two script labels here will be processed by the Custom Handler.
Create Server Functions
Create a server-side function that can be asynchronously accessed from a client call. Because at present, it does not support all the return types (don't worry, we will develop a new version based on the current version). Let's continue to use the simple ServerSideAdd function. In the code after file, add the following code to the page:
[Ajax. AjaxMethod ()]
Public int ServerSideAdd (int firstNumber, int secondNumber)
{
Return firstNumber + secondNumber;
}
Note that these functions have the Ajax. AjaxMethod attribute set. This property tells the wrapper how to create a javaScript proxy for calling on the client.
Client call
The last step is to use JavaScript to call the function. The AJAX package is responsible for creating the JavaScript function Sample. ServerSideAdd with two parameters. For this simplest function, you only need to call this method and pass two numbers:
<% @ Page Inherits = "AjaxPlay. Sample" Codebehind = "sample. aspx. cs" %>
<Html>
<Head>
<Script language = "javascript" src = "ajax/common. ashx"> </script>
<Script language = "javascript"
Src = "ajax/AjaxPlay. Sample, AjaxPlay. ashx"> </script>
</Head>
<Body>
<Form id = "Form1" method = "post" runat = "server">
<Script language = "javascript">
Var response = Sample. ServerSideAdd (100,99 );
Alert (response. value );
</Script>
</Form>
</Body>
</Html>
Of course, we do not want to use this powerful capability to warn users. This is why all client proxies (such as the JavaScript Sample. ServerSideAd function) accept other features. This feature is the callback function called to handle the response:
Sample. ServerSideAdd (100,99, ServerSideAdd_CallBack );
Function ServerSideAdd_CallBack (response ){
If (response. error! = Null ){
Alert (response. error );
Return;
}
Alert (response. value );
}
From the code above, we can see that another parameter is specified. ServerSideAdd_CallBack (see the preceding Code) is a client function used to process server responses. This callback function receives a response object that exposes three main properties.
Value -- the Value actually returned by the server-side function (whether it is a string, a custom object, or a dataset ).
Error -- Error message, if any.
Request -- xml: the original response of the http Request.
Context -- Context object.
First, check the error to see if an error has occurred. By throwing an exception in a server-side function, you can easily handle the error feature. In this simplified example, use this value to warn the user. The Request feature can be used for more information (see the next section ).
Processing type
Return complex types
The Ajax Wrapper can not only process integers returned by the ServerSideAdd function. It also supports integers, strings, double, booleans, DateTime, DataSets, DataTables, custom classes, arrays, and other basic types. All other types return their ToString values.
The returned DataSets is similar to the real. NET DataSet. Suppose a server-side function returns DataSet. We can use the following code to display the content on the client:
<Script language = "JavaScript">
// Asynchronous call to the mythical "GetDataSet" server-side function
Function getDataSet (){
AjaxFunctions. GetDataSet (GetDataSet_callback );
}
Function GetDataSet_callback (response ){
Var ds = response. value;
If (ds! = Null & typeof (ds) = "object" & ds. Tables! = Null ){
Var s = new Array ();
S [s. length] = "<table border = 1> ";
For (var I = 0; I <ds. Tables [0]. Rows. length; I ++ ){
S [s. length] = "<tr> ";
S [s. length] = "<td>" + ds. Tables [0]. Rows [I]. FirstName + "</td> ";
S [s. length] = "<td>" + ds. Tables [0]. Rows [I]. Birthday + "</td> ";
S [s. length] = "</tr> ";
}
S [s. length] = "</table> ";
TableDisplay. innerHTML = s. join ("");
}
Else {
Alert ("Error. [3001]" + response. request. responseText );
}
}
</Script>
Ajax can also return custom classes. The only requirement is that the Serializable attribute must be used. Suppose there are the following classes:
[Serializable ()]
Public class User {
Private int _ userId;
Private string _ firstName;
Private string _ lastName;
Public int userId {
Get {return _ userId ;}
}
Public string FirstName {
Get {return _ firstName ;}
}
Public string LastName {
Get {return _ lastName ;}
}
Public User (int _ userId, string _ firstName, string _ lastName ){
This. _ userId = _ userId;
This. _ firstName = _ firstName;
This. _ lastName = _ lastName;
}
Public User (){}
[AjaxMethod ()]
Public static User GetUser (int userId ){
// Replace this with a DB hit or something
Return new User (userId, "Michael", "Schwarz ");
}
}
You can register the GetUser agent by calling RegisterTypeForAjax:
Private void Page_Load (object sender, EventArgs e ){
Utility. RegisterTypeForAjax (typeof (User ));
}
In this way, you can call GetUser asynchronously on the client:
<Script language = "javascript">
Function getUser (userId ){
User. GetUser (GetUser_callback );
}
Function GetUser_callback (response ){
If (response! = Null & response. value! = Null ){
Var user = response. value;
If (typeof (user) = "object "){
Alert (user. FirstName + "" + user. LastName );
}
}
}
GetUser (1 );
</Script>
The value returned in the response is actually an object that exposes the same attributes (FirstName, LastName, and UserId) as the server object ).
Custom Converter
We have seen that the Ajax. NET package can process many different. NET types. However, except for a large number of. NET classes and built-in types, the wrapper only calls ToString () for other types that cannot be correctly returned (). To avoid this, the Ajax. NET package allows developers to create an object converter for smoothly passing complex objects between the server and the client.
Other items
Register functions in other classes
In the above example, our server-side functions are all placed in the code behind the execution page. However, there is no reason not to place these functions in a separate class file. Remember, the way the wrapper works is to find all methods with Ajax. AjaxMethod in the specified class. The required class is specified through the Second Script tag. With Ajax. Utility. RegisterTypeForAjax, we can specify any classes required. For example, it is reasonable to use our server-side functions as separate classes:
Public Class AjaxFunctions
<Ajax. AjaxMethod ()> _
Public Function Validate (username As String, password As String) As Boolean
''Do something
''Return something
End Function
End Class
By specifying the type of the class rather than the page, you can let the Ajax package create a proxy:
Private void Page_Load (object sender, EventArgs e ){
Ajax. Utility. RegisterTypeForAjax (typeof (AjaxFunctions ));
//
}
Remember that the name of the client proxy is <ClassName>. <ServerSideFunctionName>. Therefore, if the ServerSideAdd function is placed in the fictitious AjaxFunctions class above, the client call should be: AjaxFunctions. ServerSideAdd (1, 2 ).
How does proxy work?
The Second Script tag generated by the Ajax Tool (which can also be inserted manually) passes the page namespace, class name, and assembly. Based on this information, Ajax. PageHandlerFactory can use reflection to obtain detailed information about any function with specific attributes. Obviously, the processing function searches for functions with the AjaxMethod attribute and obtains their signatures (return types, names, and parameters), from the ability to create necessary client proxies. Specifically, the Package creates a JavaScript Object with the same name as the class, which provides a proxy. In other words, given a server-side class AjaxFunctions with Ajax ServerSideAdd method, we will get the AjaxFunction JavaScript Object that exposes the ServerSideAdd function. If you direct the browser to the path of the Second Script tag, you will see this action.
Returns Unicode characters.
The Ajax. NET package can return Unicode characters from the server to the client. Therefore, data must be html encoded on the server before being returned. For example:
[Ajax. AjaxMethod]
Public string Test1 (string name, string email, string comment ){
String html = "";
Html + = "Hello" + name + "<br> ";
Html + = "Thank you for your comment <B> ";
Html + = System. Web. HttpUtility. HtmlEncode (comment );
Html + = "</B> .";
Return html;
}
SessionState
The server functions may need to access session information. Therefore, you only need to tell Ajax to enable this function by passing a parameter to the Ajax. AjaxMethod attribute.
While examining the package's session capabilities, let's take a look at several other features. In this example, we have a document management system that locks documents when users edit them. Other users can request a notification when the document is available. Without AJAX, we can only wait for the user to return again to check whether the requested document is available. Obviously not ideal. It is very easy to use Ajax that supports session status.
First, write the server-side function. The objective is to traverse the entid that you want to edit (stored in the session) and return all released documents.
[Ajax. AjaxMethod (HttpSessionStateRequirement. Read)]
Public ArrayList DocumentReleased (){
If (HttpContext. Current. Session ["DocumentsWaiting"] = null ){
Return null;
}
ArrayList readyDocuments = new ArrayList ();
Int [] documents = (int []) HttpContext. Current. Session ["DocumentsWaiting"];
For (int I = 0; I <documents. Length; ++ I ){
Document document = Document. GetDocumentById (documents [I]);
If (document! = Null & document. Status = DocumentStatus. Ready ){
ReadyDocuments. Add (document );
}
}
Return readyDocuments;
}
}
Note that the value HttpSessionStateRequirement. Read is specified (Write and ReadWrite can also be used ).
Now write the JavaScript that uses this method:
<Script language = "javascript">
Function DocumentsReady_CallBack (response ){
If (response. error! = Null ){
Alert (response. error );
Return;
}
If (response. value! = Null & response. value. length> 0 ){
Var div = document. getElementById ("status ");
Div. innerHTML = "The following statements are ready! <Br/> ";
For (var I = 0; I <response. value. length; ++ I ){
Div. innerHTML + = "<a href = \" edit. aspx? Entid = "+ response. value [I]. entid +" \ ">" + response. value [I]. Name + "</a> <br/> ";
}
}
SetTimeout (''page. DocumentReleased (DocumentsReady_CallBack) '', 10000 );
}
</Script>
<Body onload = "setTimeout (''document. DocumentReleased (DocumentsReady_CallBack)'', 10000); ">
Conclusion
AJAX technology has given birth to a robust and rich Web interface that was originally available only for desktop development. The Ajax. NET package allows you to easily use this new powerful technology. Please note that the Ajax. NET Package and documentation are still under development.
Original address: http://hi.baidu.com/tianine5/blog/item/f9949acb8446d2ff52664f8a.html? # Send