Asp.net mvc +Ajax +Extjs+NHibernate 系列之Ajax

概述:

Ajax Asynchronous JavaScript +XML 关键技术在于浏览器与服务器通信而无须刷新当前页面的技术范围。在这篇中所要提出的是,

Ajax怎么去请求controller?一般的请求webservice,*.ashx等都讲的比较多。但我分享一下请求controller的技术。

详解:

1,构造XMLHttpRequest

不同浏览器构造的对象的方法不同

js代码:

var xmlHttp;

function createXMLHttpRequest() {

if (window.ActiveXObject)

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

else if (window.XMLHttpRequest)

xmlHttp = new XMLHttpRequest();

}

XMLHttpRequest对象的属性

onreadystatechange 每个状态改变时都会触发这个事件处理器,通常调用一个javascript函数

readystate 0=未初始化,1=正在加载,2=已加载,3=交互中,4=完成

responseText 服务器响应,表示一个串

responseXML xml对象,

status http状态码 关于状态码,可以在此处查询http://www.cnblogs.com/stu-acer/archive/2009/02/06/1385005.html

status text http状态码的相应文本 ,ok not found 等。

重要的几个:

200 - 服务器成功返回网页

404 - 请求的网页不存在

503 - 服务器超时

2,简单测试与controller的连接代码

客户端代码:

function StratReuest() {

createXMLHttpRequest();

var queryUrl = "/SystemConfig/AjaxConnect?flag=testconn";

queryUrl += "&timeStamp=" + new Date().getTime();

xmlHttp.open("POST", queryUrl, true);

xmlHttp.onreadystatechange = function() {

if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

//alert("服务器返回: " + xmlHttp.responseText);

IsSuccessful(xmlHttp.responseText);

}

}

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xmlHttp.send(null);

}

(1),构造queryUrl,要点在于:/SystemConfig/AjaxConnect?flag=testconn,包括,请求的controller方法"AjaxConnect",以及方法的参数"flag";

(2),然后是请求返回后的处理 if (xmlHttp.readyState == 4 && xmlHttp.status == 200) 请求已完成,且服务器成功返回网页。

(3) xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xmlHttp.send(null);这两句话必须有,不然不能请求服务器。

function IsSuccessful(responseStr) {

var messageInfo = responseStr.split('":"')[1];

var successInfo = messageInfo.split('","')[0];

if (successInfo == "successful")

alert("成功!");

else

alert("失败!"+responseStr.split('":"')[2]);

}

服务端代码:

/// <summary>

/// 测试Ajax通信连接

/// </summary>

/// <returns></returns>

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult AjaxConnect(string flag)

{

string strJson = ReadJsonStringFromRequestBody(Request.InputStream);

SystemConfig config = new SystemConfig();

config.CreateDT = DateTime.Parse("2010-6-2");

config.Creator = "测试人";

config.FieldGroup = 0;

config.FieldName = "测试";

config.FieldValue = "123";

config.UpdateDT = DateTime.Parse("2010-6-2");

config.Updator = "测试员";

string strData = SystemConfigSerize.Serized(config);

config = SystemConfigSerize.DeSerizedFromJsonString(strJson);

if (flag == "testconn")

{

MessageData data = new MessageData();

data.Flag = "successful";

data.Data = strData;

return this.Json(data);

}

else

{

MessageData data = new MessageData();

data.Flag = "failer";

data.Data = "test";

return this.Json(data);

}

}

特性标记为post,然后是返回处理的结果。this.Json(data);以为asp.net Controller有生成json字符串的方法,

返回结果为:flag:successful,data:test 字符串。

3.Ajax 添加记录到数据库

客户端:

function CreateAjaxRequest() {

var filedNameText = document.getElementById("FieldName");

var fieldValueText = document.getElementById("FieldValue");

var fieldGroupText = document.getElementById("FieldGroup");

var creatorText = document.getElementById("Creator");

var createDTText = document.getElementById("CreateDT");

var updatorText = document.getElementById("Updator");

var updateDTText = document.getElementById("UpdateDT");

var quertStr = createDTText.value;

quertStr += ",";

quertStr += creatorText.value;

quertStr += ",";

quertStr += fieldGroupText.value;

quertStr += ",";

quertStr += filedNameText.value;

quertStr += ",";

quertStr += fieldValueText.value;

quertStr += ",";

quertStr += updateDTText.value;

quertStr += ",";

quertStr += updatorText.value;

createXMLHttpRequest();

var queryUrl = "/SystemConfig/AjaxCreate?strData=" + quertStr;

queryUrl += "&timeStamp=" + new Date().getTime();

xmlHttp.open("POST", queryUrl, true);

xmlHttp.onreadystatechange = function() {

if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

//alert("服务器返回: " + xmlHttp.responseText);

IsSuccessful(xmlHttp.responseText);

}

}

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xmlHttp.send(null);

}

(1)客户端构造类似于:“2010-6-2 0:00:00,测试人,0,测试,123,2010-6-2 0:00:00,测试员”字符串,然后发送到服务器。

(2)构造quertStr,附加到请求的字符串中,然后请求服务器。

(3)必须的发送send方法。

服务端:

/// <summary>

/// 解析类似于“2010-6-2 0:00:00,测试人,0,测试,123,2010-6-2 0:00:00,测试员”字符串,写入数据库

/// </summary>

/// <param name="strData">字符串</param>

/// <returns></returns>

public ActionResult AjaxCreate(string strData)

{

try

{

string dataParam = Request.Params.Get(0).ToString();

if (string.IsNullOrEmpty(dataParam))

throw new Exception("Id没有赋值!");

SystemConfig config = SystemConfigSerize.Deserized(dataParam);

service.Save(config);

MessageData data = new MessageData();

data.Flag = "successful";

data.Data = "createInfo";

return this.Json(data);

}

catch

{

MessageData data = new MessageData();

data.Flag = "failer";

data.Data = "createInfo";

return this.Json(data);

}

}

(1)获取客户端发送过来的结果:string dataParam = Request.Params.Get(0).ToString();这句是重点。

(2)解析,然后调用service,然后添加到数据库中。

4,Ajax Json 测试通信连接

前面的都是客户端发送字符串到服务器,而现在列出,怎么使用json请求,以及在服务端的处理方式。

客户端:

function StratJsonReuest() {

createXMLHttpRequest();

var queryUrl = "/SystemConfig/AjaxJsonConnect?flag=testconn";

queryUrl += "&timeStamp=" + new Date().getTime();

xmlHttp.open("POST", queryUrl, true);

xmlHttp.onreadystatechange = function() {

if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

IsSuccessful(xmlHttp.responseText);

}

}

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

var systemModelObject = new SystemConfigModel("测试人", 0, "测试0", "测试值1", "测试人");

var systemModelJson = JSON.stringify(systemModelObject);

xmlHttp.send(systemModelJson);

}

(1) 这里用到了json2.js,在 http://www.JSON.org/json2.js 下载 。

(2) var systemModelJson = JSON.stringify(systemModelObject); Json 对象之后,用send 方法发送到服务端:xmlHttp.send(systemModelJson);

服务端:

/// <summary>

/// 测试AjaxJson通信连接

/// </summary>

/// <returns></returns>

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult AjaxJsonConnect(string flag)

{

string strJson = ReadJsonStringFromRequestBody(Request.InputStream);

SystemConfig config = new SystemConfig();

config.CreateDT = DateTime.Parse("2010-6-2");

config.Creator = "测试人";

config.FieldGroup = 0;

config.FieldName = "测试";

config.FieldValue = "123";

config.UpdateDT = DateTime.Parse("2010-6-2");

config.Updator = "测试员";

string strData = SystemConfigSerize.Serized(config);

config = SystemConfigSerize.DeSerizedFromJsonString(strJson);

if (flag == "testconn")

{

MessageData data = new MessageData();

data.Flag = "successful";

data.Data = config.ToString();

return this.Json(data);

}

else

{

MessageData data = new MessageData();

data.Flag = "failer";

data.Data = "deleteInfor";

return this.Json(data);

}

}

private string ReadJsonStringFromRequestBody(Stream requstStrem)

{

string b = string.Empty;

if (requstStrem == null) return b;

try

{

long length = requstStrem.Length;

byte[] buffer = new byte[length];

requstStrem.Read(buffer, 0, (int)length);

//string a=Encoding.ASCII.GetString(buffer);

string a = Encoding.UTF8.GetString(buffer);

b=a.ToString().TrimEnd(new char['0']);

}

catch (Exception exp)

{

throw exp;

}

return b;

}

(1)服务端获取请求的json数据了,string strJson = ReadJsonStringFromRequestBody(Request.InputStream);通过读取inputstream来获取字符串,在获取

字符串的时候 string a = Encoding.UTF8.GetString(buffer);用到了utf8的编码格式,否则,汉字显示不了。

5,Ajax json 详情

Ajax json 添加与删除,此处不再赘述。在添加一个关于详情的,服务端返回一长串之后,客户端的处理方式,因为是多个对象。

客户端:

function DetailsRequest(id) {

createXMLHttpRequest();

var flagTxt = document.getElementById("flag");

if (flagTxt.value != "Create") {

var queryUrl = "/SystemConfig/AjaxJsonDetail?id=" + id.toString();

queryUrl += "&timeStamp=" + new Date().getTime();

xmlHttp.open("POST", queryUrl, true);

xmlHttp.onreadystatechange = function() {

if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

var messageInfo = xmlHttp.responseText.split('":"')[1];

var successInfo = messageInfo.split('","')[0];

if (successInfo == "failer") return;

if (eval('(' + xmlHttp.responseText + ')') != null) {

var obj = eval('(' + xmlHttp.responseText + ')');

var filedNameText = document.getElementById("FieldName");

var fieldValueText = document.getElementById("FieldValue");

var fieldGroupText = document.getElementById("FieldGroup");

if (obj.FieldName != null) {

filedNameText.value = obj.FieldName;

fieldValueText.value = obj.FieldValue;

fieldGroupText.value = obj.FieldGroup;

}

}

}

}

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xmlHttp.send(null);

}

}

(1)请求只是在请求字符串后,附加id的值,是给服务器传入id值,然后返回一个对象/SystemConfig/AjaxJsonDetail?id=" + id.toString()

(2)请求后的处理

if (eval('(' + xmlHttp.responseText + ')') != null) {

var obj = eval('(' + xmlHttp.responseText + ')');

var filedNameText = document.getElementById("FieldName");

var fieldValueText = document.getElementById("FieldValue");

var fieldGroupText = document.getElementById("FieldGroup");

if (obj.FieldName != null) {

filedNameText.value = obj.FieldName;

fieldValueText.value = obj.FieldValue;

fieldGroupText.value = obj.FieldGroup;

}

}

JavaScript eval方法,可以直接序列化字符串为对象,而且可以通过obj.FieldName访问对象的属性。

服务端:

/// <summary>

/// SystemConfig详情

/// </summary>

/// <param name="id"></param>

/// <returns></returns>

public ActionResult AjaxJsonDetail(string id)

{

try

{

string idStr = Request.Params.Get(0).ToString();

SystemConfig config = service.GetById(decimal.Parse(idStr));

if (config == null)

{

MessageData data = new MessageData();

data.Flag = "failer";

data.Data = "没有查找到数据!";

return this.Json(data);

}

else

return this.Json(config);

}

catch (Exception exp)

{

MessageData data = new MessageData();

data.Flag = "failer";

data.Data = exp.ToString();

return this.Json(data);

}

}

(1)同样使用Request.Params.Get(0).ToString()获取到客户端传入的id值。

(2)Service从数据库里查询。然后json后,传到客户端。

6,Ajax 查询所有

客户端:

function AllRequest() {

createXMLHttpRequest();

var queryUrl = "/SystemConfig/AjaxJsonIndex?timestape=" + new Date().getTime();

xmlHttp.open("POST", queryUrl, true);

xmlHttp.onreadystatechange = function() {

if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

var messageInfo = xmlHttp.responseText.split('":"')[1];

var successInfo = messageInfo.split('","')[0];

if (successInfo == "failer") return;

if (eval('(' + xmlHttp.responseText + ')') != null) {

var obj = eval('(' + xmlHttp.responseText + ')');

CreateTable(obj);

}

}

}

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xmlHttp.send(null);

}

function CreateTable(obj) {

var data = new Array();

data.push('<table );

data.push('<th>FieldName</th><th>FieldValue</th><th>FieldGroup</th><th>Creator</th><th>CreateDT</th><th>Updator</th><th>UpdateDT</th><th>PkId</th>');

for (var i = 0; i < obj.length; i++) {

data.push('<tr>');

data.push('<td>' +obj[i].FieldName+'</td>');

data.push('<td>' +obj[i].FieldValue+'</td>');

data.push('<td>' +obj[i].FieldGroup+'</td>');

data.push('<td>' + obj[i].Creator + '</td>');

if (obj[i].CreateDT != null)

data.push('<td>' + new Date(parseInt(obj[i].CreateDT.substring(6, 13))).toLocaleDateString() + '</td>');

else

data.push('<td>' + obj[i].CreateDT + '</td>');

data.push('<td>' + obj[i].Updator + '</td>');

if (obj[i].UpdateDT != null)

data.push('<td>' + new Date(parseInt(obj[i].UpdateDT.substring(6, 13))).toLocaleTimeString() + '</td>');

else

data.push('<td>' + obj[i].UpdateDT + '</td>');

data.push('<td>' +obj[i].PkId+'</td>');

data.push('</tr>');

}

data.push('</tbody><table>');

document.getElementById('table1').innerHTML = data.join('');

}

(1)客户端直接发送请求即可/SystemConfig/AjaxJsonIndex?

(2)客户端的处理过程,Javascript 的eval方法处理字符串之后,形成object对象,我在这里做的是,动态构造了一个table,然后显示客户端。

而对object对象的访问,因为是多条记录,可以循环访问,然后直接访问属性即可obj[i].FieldName。

服务端:

/// <summary>

/// Json查询所有配置列表

/// </summary>

/// <returns></returns>

public ActionResult AjaxJsonIndex()

{

List<SystemConfig> configList = new List<SystemConfig>();

configList = service.GetAll();

if (configList != null || configList.Count==0)

{

return this.Json(configList);

}

else

{

MessageData data = new MessageData();

data.Flag = "failer";

data.Data = "没有查找到数据!";

return this.Json(data);

}

}

7,Ajax xml 请求

既然是Ajax,那么请求xml总要有吧

客户端:

function StartXMLRequest() {

createXMLHttpRequest();

var queryUrl = "/SystemConfig/AjaxXMlDetail?;

queryUrl += "&timeStamp=" + new Date().getTime();

xmlHttp.open("POST", queryUrl, true);

xmlHttp.onreadystatechange = function() {

if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

ReadXml()

}

}

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xmlHttp.send(null);

}

function ReadXml() {

var xmlDoc = xmlHttp.responseXML;

var pkIdNode = xmlDoc.getElementsByTagName("PkId");

var fileNameNode = xmlDoc.getElementsByTagName("FieldName");

var filedValueNode = xmlDoc.getElementsByTagName("FieldValue");

var creatorNode = xmlDoc.getElementsByTagName("Creator");

var updatorNode = xmlDoc.getElementsByTagName("Updator");

var outString = pkIdNode[0].text + "***" + fileNameNode[0].text + "***" + filedValueNode[0].text;

alert(outString);

}

(1)请求,同样附加参数。

(2)处理结果, var xmlDoc = xmlHttp.responseXML; var pkIdNode = xmlDoc.getElementsByTagName("PkId");通过属性xmlHttp.responseXML直接获得xml,通用的操作。

服务端:

public ActionResult AjaxXMlDetail(string id)

{

string dataParam = Request.Params.Get(0).ToString();

if (!string.IsNullOrEmpty(dataParam))

{

SystemConfig config = service.GetById(int.Parse(dataParam));

if (config == null) return RedirectToAction("SystemConfigNotFound");

XMLResult result=new XMLResult(config);

return result;

}

else

return RedirectToAction("SystemConfigNotFound");

}

XMLResult可以直接序列化对象。

服务端在接受到请求后,查询,然后json对象,返回给客服端。

技术要点:

Ajax 请求时主流的操作模式,做到页面的局部刷新即可,通信是客户端与服务端的处理过程。信息的交互。

总结

Ajax 通过异步的请求来完成于服务器的交互。