【总结】Ajax Asp.Net 交互处理方式(三)

     在第二章中已经对前台处理部分进行了编码,此章将探讨后台(.NET,C#为例)部分的编码。
从第一章的构架分析:后台的任务主要是构造符合前台解析规则的“消息协议”。接下来我们先分析这种协议的特点:

1、需要有头信息(必须),用于对请求状态的标示。包括 _Success,_Fail,_Action 三个状态

2、必须有自定义信息,用于进行用户自定义数据的传送

3、对头信息中的标示采用属性方式设定,对于自定义信息中的数据必须能实现:添加、删除单个

    删除所有、重设单个的功能

4、最后必须输出标准的Json字串

根据以上特点便可以编码出这种消息协议对象(JsonInfo)。因为要使用Json作为传输介质,因此

我们必须引用“Newtonsoft.Json” 即Json.Net dll组件。为了让我们的JsonInfo能够支持更多的对象

序列化,还必须考虑弥补Json.Net对DataSet和DataTable的不足。我们需要增加这两种解析方式。

从上面的四点可知,不论是头信息还是自定义信息,其实都是Key/Value的形式,我们可以通过编程

手段将两者归为一个对象中。这里我采用泛型Dictionary<string, object>来存储信息。代码见下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using System.Data;

namespace PersonalTool
{
    /// <summary>
    /// 用于进行Ajax数据交流的后台类
    /// </summary>
    public class JsonInfo
    {
        Dictionary<string, object> DT = new Dictionary<string, object>();
        static List <string> ProtectKey = new List<string> {"_Success","_Fail","_Action"};

        /// <summary>
        /// 返回所有的键值字典
        /// </summary>
        public Dictionary<string,object> ItemDictionary
        {
            get { return DT; }
        }

        /// <summary>
        /// 成功信息
        /// </summary>
        public string Success {
            get { return DT["_Success"].ToString (); }
            set { DT["_Success"] = value; }
        }
        /// <summary>
        /// 失败信息
        /// </summary>
        public string Fail   {
            get { return DT["_Fail"].ToString (); }
            set { DT["_Fail"] = value; }
        }
        /// <summary>
        /// 后续动作
        /// </summary>
        public string Action {
            get { return DT["_Action"].ToString (); }
            set { DT["_Action"] = value; }
        }

        public JsonInfo()
        {
            DT.Add("_Success", "");
            DT.Add("_Fail", "");
            DT.Add("_Action", "");

        }

        /// <summary>
        /// 添加自定义键值
        /// </summary>
        /// <param name="KeyName">键名称<para>(不能为以下值 _Success,_Fail,_Action)</para></param>
        /// <param name="Object">键对象</param>
        public void AddItem(string KeyName, object Object)
        {
            if (ProtectKey.Contains(KeyName))
                SetItem(KeyName, Object);
            else
                DT.Add(KeyName, Object);

        }

        /// <summary>
        /// 设定键值
        /// </summary>
        /// <param name="KeyName">键名</param>
        /// <param name="Object">键值对象</param>
        public void SetItem(string KeyName, object Object)
        {
            DT[KeyName] = Object;

        }

        /// <summary>
        /// 删除指定的键
        /// </summary>
        /// <param name="KeyName"></param>
        public void DelKey(string KeyName)
        {
            if (ProtectKey.Contains(KeyName))
                SetItem(KeyName, "");
            else
            {
                if (DT.ContainsKey(KeyName)) DT.Remove(KeyName);
            }
        }

        /// <summary>
        /// 清除所有的键值,恢复默认值
        /// </summary>
        public void ClearAll()
        {
            DT.Clear();
            DT.Add("_Success", "");
            DT.Add("_Fail", "");
            DT.Add("_Action", "");
        }

        /// <summary>
        /// 返回格式化了的Json字串
        /// </summary>
        /// <returns></returns>
        public string ToJson()
        {
            return JsonConvert.SerializeObject(DT,new DataSetConverter(),new DataTableConverter());
        }

        /// <summary>
        /// 输出格式化了的Json字串,并结束当前的处理流(即Response.End()),因此在使用时需要考虑try…catch的情况
        /// </summary>
        public void ToJsonAndStop()
        {
            System.Web.HttpContext.Current.Response.Write(ToJson());
            System.Web.HttpContext.Current.Response.End();

        }

     }

    /// Json 补充的类

    class DataSetConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(DataSet).IsAssignableFrom(objectType);
        }
        public override Object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer) {
            return null;
        }
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            DataSet ds = (DataSet)value;
            writer.WriteStartObject();
            foreach (DataTable dt in ds.Tables)
            {
                writer.WritePropertyName(dt.TableName);
                writer.WriteStartArray();
                foreach (DataRow dr in dt.Rows)
                {
                    writer.WriteStartObject();
                    foreach (DataColumn dc in dt.Columns)
                    {
                        writer.WritePropertyName(dc.ColumnName);
                        writer.WriteValue(dr[dc].ToString());
                    }
                    writer.WriteEndObject();
                }
                writer.WriteEndArray();
            }
            writer.WriteEndObject();
        }
    }

    class DataTableConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            DataTable dt = (DataTable)value;

            writer.WriteStartArray();
            foreach (DataRow dr in dt.Rows)
            {
                writer.WriteStartObject();
                foreach (DataColumn dc in dt.Columns)
                {
                    writer.WritePropertyName(dc.ColumnName);
                    writer.WriteValue(dr[dc].ToString());
                }
                writer.WriteEndObject();
            }
            writer.WriteEndArray();

        }
        public override Object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
        {
            return null;
        }
        public override bool CanConvert(Type objectType)
        {
            return typeof(DataTable).IsAssignableFrom(objectType);
        }
    }

}

从上可以看出对于头信息中的三个标示采取一定的保护措施。在Json 补充的类,我们扩展了原有的

转换,由于本消息协议只关心序列化,因此在对DataTableConverter和DataSetConverter中ReadJson

这个抽象方法上并未做实现。

到此,后台部分也就完成了。后台不但能够方便的实现常用对象的序列化,同时还可以很好的序列化DataSet

和DataTable。有了这些对于常用的交互需求应该算是有了很好的支持。

小提示:

  1、  对于String,Int……等对象序列化后是很好通过Js访问的,这里需要指出是对于DataSet和DataTable的访问。

当然您可以查看ToJson方法输出的字串信息。在这里我简要说明一下。

如果是DataSet则返回的信息格式参考如下:

服务端:XX.AddItem(“DataSet”,DS);//DS为一个DataSet对象

客户端收到的字串:

DataSet”:{“Table1”:[

                                  {“UserName”:”FoxHunter”,”Age”:23,”Sex”:1},

                                  {“UserName”:”FoxHunter2”,”Age”:23,”Sex”:1},…],

                   ”Table2”:[

                                  {“Right”:”Admin”,”NickName”:”Fox”},

                                  {“Right”:”Guest”,”NickName”:”Guest”},…],…}

Js转换成Object后:

  ?.DataSet.Table1[0].UserName ; ?.DataSet.Table1[1].Age ; ?.DataSet.Table2[0].Right ; 这样您就可以方便的访问了。

如果是DataTable则情况如下:

服务端:XX.AddItem(“DataTable”,DT);//DT为一个DataTable对象

客户端收到的字串:

DataTable“:[

                   {“UserName”:”FoxHunter”,”Age”:23,”Sex”:1},

                   {“UserName”:”FoxHunter2”,”Age”:23,”Sex”:1},…]

JS转化为Object后:

?.DataTable[0].UserName ; ?.DataTable[1].Age ;

总之记住规律(注意颜色标示):对于表(例如 Table1 Table2 DataTable )的访问可以直接书写其名字。而对于表格中的Row(例如 方括号中的 大括号对 表示Row)必须通过在前面的表名中加上索引值来访问(因为他们是数组的形式),当你访问到Row后,row中的字段值就可以直接用”.“语法来访问了。“?”是因为我省略了一个对象这个对象是前台回调函数中的第一个参数,因此此处无法标明。

2、您可以在前一篇的JS代码中加入以下内容,以便于您Ajax交互时查看后台传回的字串(调试完后记得删除,下面粗体部分)

 $.ajax({
                     type: reqObject.type,
                     dataType: "json", //设置解析数据方式为json
                     url: reqObject.url,
                     cache: reqObject.cache,
                     data: reqObject.data,
                    complete: doJsonInfoComplete,//正式使用时记得删除或注掉
                     success: function(e) { doJsonInfoCallBack(e, reqObject) },  //成功执行ajax后的回调函数,e为服务端返回的Javascript Object对象
                     timeout: reqObject.timeout, // 超时时间
                     error: function(XMLHttpRequest, textStatus, errorThrown) { doJsonInfoError(XMLHttpRequest, textStatus, errorThrown, reqObject) }  //ajax执行发生错误后调用
                 });
     var doJsonInfoComplete = function(XMLHttpRequest, textStatus) {
         alert(XMLHttpRequest.responseText);
         }

         var doJsonInfoCallBack = function(e, reqObject) {...

OK,在此后台和注意事项便交代完毕了,相信对Asp.Net和Javascript了解的应该已经知道整个

模型如何使用了,接下来就是最后一章,关于模型使用的演示代码和所有源文件了。
[Come From: http://foxhunter.yo2.cn/articles/ajax-aspnet-03.html]

转载于:https://www.cnblogs.com/foxhunter/archive/2009/07/31/ajax-aspnet-03.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值