博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

AJAX客户端和服务器之间的传值理解

Posted on 2010-01-27 13:48  hyd309  阅读(1585)  评论(0编辑  收藏  举报

1。AJAX 值在客户端和服务器之间的传递,异步。
原理性的:

客户端的脚本:
javascript:
var xmlhttp=null;
try{
xmlhttp=new XMLHttpRequest();}
catch(e){
   try{xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");}
   catch(e) {xmlhttp=new ActivexObject("Mcriosoft.XMLHTTP");}
            }
    var t=document.getElementById("sug").value;
    xmlHttp.open("GET","index.aspx?t="+t,false);
    xmlHttp.send();
    if(xmlHttp.readyState == 4){ 
       document.getElementById("mydiv").innerHTML=xmlHttp.responseText;} 
(此处还可以是xmlHttp.responseXML(返回的是XML),当返回是字符或数字的时候,就用responseText)
}

服务器端的代码:index.aspx.cs
string t=Request.QueryString["t"];
        string hint="";

string[] str=new string[8];
        str[0] = "aaa";
        str[1] = "bb";
        str[2] = "ces";
        str[3] = "dnd";
        str[4] = "ews";
        str[5] = "addes";
        str[6] = "assnd";
        str[7] = "cccws";
        for (int i = 0; i < str.Length; i++)
            if (t == str[i].Substring(0, t.Length))
                if (hint == "")
                    hint = str[i];
                else
                    hint = hint+"</br>"+str[i];
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.Append("<div  style='background-color:Gray; width:100px'>"+hint+"</div>");
            Response.Write(sb.ToString());
(主要是Response.Write的作用。注意,index.aspx只有后台代码,而前台的代码只保留最上面一行,其他的都要删掉,即保留<%#......#%>的黄色体;)

总结:
客户端的异步调用,通过JAVASCRIPT,创建XMLHttp,然后OPEN,SEND到其他的页面,(这里是页面,还有其他的方式,下面接着讲),然后用responseText运载着返回值回来。在客户端就可以用这个值了,而服务器端没有什么变化,只负责生成一个值或字符或XML(随着客户端的OPEN不同,服务器的不同);

2。ASP.NET AJAX 特有的:

客户端:同样是Javascript:而服务器端最好应用WebService,(当然用方法1当然可以)这里我们不用方法1,用这个方式,不用OPEN指向到一个页面,也就是不指向到一个后缀名为aspx的页面,而是指向一个后缀名为asmx的程序;而这个指向过程是在<body><form><asp:scriptmanager>...asmx..</asp:scriptmanager></form></body>,不再在javascript中实现。
如下,<asp:scriptmanager>就是专门管理脚本的,
<asp:scriptmanager runat="server" ID="sm">
<Services>
<asp:ServiceReference Path="WebService.asmx" />
</Services>
</asp:scriptmanager>
接着在Javascript中要完成的代码有:


function btn_onclick(){   
    var id=document.getElementById("id").value;
    WebService.HelloWorld(id,onsucceesed);这里调用的时候是两个。。。。。函数onsucceesed被作为参数调用,而且这里自己没有带参数
    }

function onsucceesed(result){           onsucceesed有一个参数
    $get("divs").innerHTML=result;
    }


这里定义的函数onsucceesed参数不一定非要是result,是个变量就可以。注意作为一个参数被调用的时候连括号都没有,更没有参数了,而定义这个函数的时候要带着。在WebService.HelloWorld调用的时候是两个参数,而asmx文件里函数定义WebService.HelloWorld的时候是只有第一个参数。后面的这个参数是个函数名。

服务器端:见后台的WebService程序:

①using System.Web.Script.Services;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
②[ScriptService]
public class WebService : System.Web.Services.WebService {

    public WebService () {

        //如果使用设计的组件,请取消注释以下行
        //InitializeComponent();
    }

    [WebMethod]
    public string HelloWorld(int id) {只有一个参数
        string re = "";
        using (SqlConnection con = new SqlConnection("Server=.;DataBase=HGSTUDY;uid=sa;pwd=.."))
        {
            con.Open();
            
SqlCommand read = new SqlCommand(string.Format("select * from GL_STU_ADD where G_ID={0}",id),con);
            SqlDataAdapter ad = new SqlDataAdapter();
            ad.SelectCommand = read;
            DataSet ds = new DataSet();
            ad.Fill(ds, "tab");
            foreach(DataRow dr in ds.Tables[0].Rows)
            { re += dr["GA_NAME"].ToString()+"<br/>"; }
            return re;
        }
        //return id + "is Ok!";  这个是简单的返回一个字符串,而没有连接到数据库中。可以说明问题。
    }   
}

总结:应用WebService更方便,注意要返回return;

3。到目前为止,我掌握的返回到客户端的数据类型有四类:

3.1。是上面的例子里的返回一个字符串,返回是“....”,用public string ;在客户端直接用。
3.2。是数值类型,返回是个具体的数值,用public int;在客户端直接用。
3.3。是DataTable,返回的是一个表,用public DataTable;        在客户端要转换,解析这个表
下面是三种返回DataTable的方式          ********重要,效果最好
3.3.1  连接到数据库 DataTable.Load(SqlDataReader)
[WebMethod]
    public DataTable getData(int id)
    {
        string result = string.Empty;
        DataTable dt = new DataTable();
        using (SqlConnection con = new SqlConnection("Server=.;DataBase=HGSTUDY;uid=sa;pwd=yao"))
        {
            con.Open();
            SqlCommand command = new SqlCommand(string.Format("select GS_ID as 序号,GS_CONENT as 内容 from GL_STUDY where GS_STYNAME_ID={0}", id), con);          
            using (SqlDataReader sdr=command.ExecuteReader())
            {
                dt.Load(sdr);
            }       
        }
        return dt;
    }

3.3.2一般的值 DataTable 增加列,再将列增加到行中
[WebMethod]
    public DataTable GetDataTable(string tableName)
    {
        DataTable table = new DataTable(tableName);
        table.Columns.Add(new DataColumn("ID", typeof(int)));
        table.Columns.Add(new DataColumn("Name", typeof(string)));
             for (int i = 0; i < 5; ++i)   
               {
                   DataRow newRow = table.NewRow();
                   newRow["ID"] = i;
                   newRow["Name"] = string.Format("name{0}",i);
                   table.Rows.Add(newRow);
               }
    return table;
    }
3.3.3数据库中,增加列,再增加行(以上两种的结合)
[WebMethod]
    public DataTable xmltotable2()
    {        
        using (SqlConnection con = new SqlConnection("Server=.;DataBase=HGSTUDY;uid=sa;pwd=yao"))
        {
            con.Open();
            DataTable dt = new DataTable();
            SqlCommand commd = new SqlCommand("select CODE_VALUE,CODE_NAME from CD_HGNAME", con);
            SqlDataReader dr = commd.ExecuteReader();
            dt.Columns.Add("0zhi");
            dt.Columns.Add("1zhi");
            while (dr.Read())
            {
                dt.Rows.Add(new object[] {dr.GetValue(0), dr.GetValue(1)}); //OR: dt.Rows.Add(dr.GetValue(0), dr.GetValue(1));         
            }
            return dt;           
        }       
    }

JS客户端解析过程:WebService.getData(did,onsucce);
function onsucce(re){
    var idColname=re.columns[0].name;
    var nameColName=re.columns[1].name;
    var rows=re.rows;
    var builder=new Sys.StringBuilder("<table border='0'>");
    builder.append(String.format(" <tr bgcolor=#ffccff><td align=center>{0}</td><td align=center>{1}</td></tr>",idColname,nameColName));
    for(var rowIndex=0;rowIndex<rows.length;++rowIndex){
    builder.append(String.format(" <tr onmousemove=this.bgColor='#CCCCCC' onmouseout=this.bgColor='white'><td style=font-size:12px>{0}</td><td style=font-size:12px>{1}</td></tr>",rows[rowIndex][idColname],rows[rowIndex][nameColName]));}
    builder.append("</table>");
    $get("result").innerHTML=builder.toString();
    }

3.4。是xml流,或则叫XML字符串,用public string
[WebMethod]
    public string GetXML(int id)
    {
        using (SqlConnection con = new SqlConnection("server=.;database=HGSTUDY;uid=sa;pwd=yao"))
        {
            con.Open();
            SqlCommand com = new SqlCommand(string.Format("select GS_ID as 序号,GS_CONENT as 内容 from GL_STUDY where GS_STYNAME_ID={0}", id), con);
            com.CommandType = CommandType.Text;
            DataSet ds = new DataSet("DATASET");
            SqlDataAdapter sda = new SqlDataAdapter();
            sda.SelectCommand = com;
            sda.Fill(ds, "DATATABLE");
            XmlDocument xmldoc = new XmlDocument();
           return ds.GetXml();
        }
    }
返回的re = "<DATASET>
  <DATATABLE>
    <序号>5</序号>
    <内容>衢州</内容>
  </DATATABLE>
  <DATATABLE>
    <序号>6</序号>
    <内容>衢州dddd</内容>
  </DATATABLE>
  <DATATABLE>
    <序号>7</序号>
    <内容>阿嫂豆腐丝大发</内容>
  </DATATABLE>
</DATASET>"

解析过程:WebService.GetXML(id,onsucceesed);
function onsucceesed(re){   
     var domxml=new ActiveXObject("Microsoft.XMLDOM");
    domxml.loadXML(re);
    var obj=domxml.selectSingleNode("DATASET").selectSingleNode("DATATABLE");
    $get("div_txt").innerHTML=obj.selectSingleNode("内容").text;
    }

总结:个人最喜欢最后一种,在解析的时候很清楚里面的字段。

(题外话:抛开AJAX不说,也就是不在客户端调用它,如果只在服务器端调用这个WebService,上面的③不用加了,只需在后台把它当作一个类,先定义一个实例,再调其中的函数。比如:
WebService webs = new WebService();
        webs.HelloWorld(20);