2_UseAsyncCommLayer.aspx
<head runat="server">
<title>Use Async Communication Layer</title>
<script language="javascript" type="text/javascript">
var webRequest = null;
function sendRequest(action)
{
webRequest = new Sys.Net.WebRequest();
webRequest.set_url("Handlers/ScriptReferenceExecutor.ashx");
webRequest.get_headers()["action"] = action;
webRequest.set_body("Hello World!");
webRequest.set_timeout(3000);
debugger;
webRequest.set_executor(new Sys.Net.ScriptReferenceExecutor());
webRequest.add_completed(onCompleted);
webRequest.invoke();
}
function onCompleted(response, eventArgs)
{
if (response.get_aborted())
{
alert("Request aborted!");
}
else if (response.get_responseAvailable())
{
var statusCode = response.get_statusCode();
if ((statusCode < 200) || (statusCode >= 300))
{
alert("Error occurred!");
}
else
{
alert(response.get_responseData());
}
}
else if (response.get_timedOut())
{
alert("Request timed out!");
}
else
{
alert("Error occurred!");
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug">
<Scripts>
<asp:ScriptReference Path="ScriptReferenceExecutor.js" />
</Scripts>
</asp:ScriptManager>
<input type="button" value="Normal" onclick="sendRequest('normal');" />
<input type="button" value="Error" onclick="sendRequest('error');" />
<input type="button" value="Timeout" onclick="sendRequest('abc')" />
<input type="button" value="Abort" onclick="webRequest.get_executor().abort()" />
</form>
</body>
ScriptReferenceExecutor.js
Sys.Net.ScriptReferenceExecutor = function()
{
Sys.Net.ScriptReferenceExecutor.initializeBase(this);
this._responseAvailable = false;
this._timedOut = false;
this._aborted = false;
this._started = false;
this._responseData = null;
this._statusCode = 0;
this._statusText = null;
this._uniqueKey = null;
this._timer = null;
this._scriptElement = null;
}
Sys.Net.ScriptReferenceExecutor.prototype =
{
get_responseAvailable : function()
{
return this._responseAvailable;
},
get_timedOut : function()
{
return this._timedOut;
},
get_aborted : function()
{
return this._aborted;
},
get_started : function()
{
return this._started;
},
get_responseData : function()
{
return this._responseData;
},
get_statusCode : function()
{
return this._statusCode;
},
get_statusText : function()
{
return this._statusText;
},
get_xml : function()
{
return new XMLDOM(this.get_responseData());
},
executeRequest : function()
{
this._started = true;
var request = this.get_webRequest();
var serializer = Sys.Serialization.JavaScriptSerializer;
var scriptUrl = request.get_url() + "?";
scriptUrl += (("headers=") + encodeURIComponent(serializer.serialize(request.get_headers())));
scriptUrl += ("&body=" + encodeURIComponent(serializer.serialize(request.get_body())));
var uniqueKey = this._uniqueKey = this._generateUniqueKey();
scriptUrl += ("&uniqueKey=" + encodeURIComponent(serializer.serialize(uniqueKey)));
Sys.Net.ScriptReferenceExecutor._executors[uniqueKey] = this;
var scriptElement = this._scriptElement = document.createElement("script");
scriptElement.type = "text/javascript";
scriptElement.language = "javascript";
scriptElement.src = scriptUrl;
document.getElementsByTagName("head")[0].appendChild(scriptElement);
var timeout = request.get_timeout();
if (timeout > 0)
{
this._timer = window.setTimeout(
Function.createDelegate(this, this._onTimeout), timeout);
}
},
_onTimeout : function()
{
this.complete(null, null, null, false, true, false);
},
abort : function()
{
this.complete(null, null, null, false, false, true);
},
_generateUniqueKey : function()
{
return Math.random().toString();
},
complete : function(statusCode, statusText, body, responseAvailable, timedOut, aborted)
{
this._statusCode = statusCode;
this._statusText = statusText;
this._responseData = body;
this._responseAvailable = responseAvailable;
this._timedOut = timedOut;
this._aborted = aborted;
if (this._timer)
{
window.clearTimeout(this._timer);
}
document.getElementsByTagName("head")[0].removeChild(this._scriptElement);
delete Sys.Net.ScriptReferenceExecutor._executors[this._uniqueKey];
this.get_webRequest().completed(Sys.EventArgs.Empty);
}
}
Sys.Net.ScriptReferenceExecutor.registerClass("Sys.Net.ScriptReferenceExecutor", Sys.Net.WebRequestExecutor);
Sys.Net.ScriptReferenceExecutor._executors = new Object();
Sys.Net.ScriptReferenceExecutor.complete = function(uniqueKey, statusCode, statusText, body)
{
var executor = Sys.Net.ScriptReferenceExecutor._executors[uniqueKey];
if (executor)
{
executor.complete(statusCode, statusText, body, true, false, false);
}
}
ScriptReferenceExecutor.ashx
<%@ WebHandler Language="C#" Class="ScriptReferenceExecutor" %>
using System;
using System.Web;
using System.Collections.Generic;
using System.Web.Script.Serialization;
public class ScriptReferenceExecutor : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
// context.Response.Write("alert('Message Received!');");
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, string> headers = serializer.Deserialize<Dictionary<string, string>>(
context.Request.QueryString["headers"]);
string body = serializer.Deserialize<string>(context.Request.QueryString["body"]);
string uniqueKey = serializer.Deserialize<string>(context.Request.QueryString["uniqueKey"]);
string action = headers["action"];
if (action == "normal")
{
this.SendResponse(context, uniqueKey, 200, "OK", "You've send: " + body);
}
else if (action == "error")
{
this.SendResponse(context, uniqueKey, 500, "Error", null);
}
else
{
System.Threading.Thread.Sleep(5000);
}
}
private void SendResponse(HttpContext context, string uniqueKey, int statusCode, string statusText, string body)
{
context.Response.Write("Sys.Net.ScriptReferenceExecutor.complete('" + uniqueKey + "', ");
context.Response.Write("'" + statusCode + "', ");
context.Response.Write("'" + statusText + "', ");
context.Response.Write(new JavaScriptSerializer().Serialize(body) + ");");
}
public bool IsReusable {
get {
return false;
}
}
}