Losesoul

扩展MagicAjax支持DataSet、DataTable等数据集的传递

最近手头接到一个项目,他们前期是用MagicAjax做的Ajax应用。MagicAjax用起来到是简单,但是复杂的应用,觉得力不从心。最近无意发现AjaxPro发布了AjaxPro.JSON类。比较顺利的把这个类移植到了MagicAjax上,效果还不错,贴出来备忘。
该扩展主要有2个重要部分,Convert.js和AjaxHelper.cs。Convert.js主要是将AjaxPro的Core.js和Convert.js的关键实现整合在一起,并在ojbect扩展了个invoke方法。详细的内容见demo中的Converter.js


AjaxHelper主要是对AjaxPro.JSON的调用,仿照AjaxPro的实现,代码如下
using System;
using System.Reflection;
using System.Collections;
using MagicAjax;
namespace MagicAjax.Extend
{
/// <summary>
/// AjaxHelper 的摘要说明。
/// </summary>
public class AjaxHelper
{
#region 成员
private static AjaxHelper   _instance;
private IList     _methods;
private System.Type   _currentClass;
private System.Web.UI.Page _page;
private System.Text.StringBuilder _builder;
#endregion
#region 属性
public static AjaxHelper Instance
{
get
{
if(null == _instance)
_instance = new AjaxHelper();
return _instance;
}
}
protected Type CurrentClass
{
get
{
return _currentClass;
}
set
{
_currentClass = value;
}
}
protected System.Web.UI.Page CurrentPage
{
get
{
return _page;
}
set
{
_page = value;
}
}
protected System.Text.StringBuilder ScriptBulilder
{
get
{
if(null == _builder)
_builder = new System.Text.StringBuilder();
return _builder;
}
}
protected IList Methods
{
get
{
if(null == _methods)
_methods = GetMethodsByClass();
return _methods;
}
}
#endregion

#region 方法
private AjaxHelper()
{
//
// TODO: 在此处添加构造函数逻辑
//
}

/// <summary>
/// 注册回调方法所在的类
/// </summary>
/// <param name="type"></param>
/// <param name="page"></param>
public void RegisterType(System.Type type,System.Web.UI.Page page)
{
this.CurrentPage = page;
//1 比较两个对象是否相等
if(!System.Type.Equals(type,CurrentClass))
{
CurrentClass = type;
_methods   = null;
ScriptBulilder.Remove(0,this.ScriptBulilder.Length);

//1.1 重新组织前台方法
ScriptBulilder.Append("<script language=\"javascript\" type=\"text/javascript\">\r\n");
//1.1.1 组织命名空间方法
BuilderNameSpaceScript();
//1.1.2 组织回调方法
ScriptBulilder.Append(string.Format("Object.extend({0}_class.prototype,",this.CurrentClass.FullName));
ScriptBulilder.Append("{\r\n");
foreach(MethodInfo info in Methods)
{
BuilderMethodScript(info);
}
//移除多余的“,\r\n”
if(Methods.Count > 0)
{
ScriptBulilder.Remove(ScriptBulilder.Length-(",\r\n".Length),",\r\n".Length);
}
this.ScriptBulilder.Append("});\r\n");
this.ScriptBulilder.Append(string.Format("{0} = new {0}_class();\r\n",this.CurrentClass.FullName));
this.ScriptBulilder.Append("</script>");

}

//2 将前台的回调脚本写到前台
if(!this.CurrentPage.IsClientScriptBlockRegistered(this.CurrentClass + "_class"))
{
this.CurrentPage.RegisterClientScriptBlock(this.CurrentClass + "_class",this.ScriptBulilder.ToString());
}
//3 处理当期后台的回调方法
if(MagicAjax.MagicAjaxContext.Current.IsAjaxCallForPage(this.CurrentPage) &&
string.Empty != MagicAjaxContext.Current.AjaxCallArgument)
{
AjaxCallBack(MagicAjaxContext.Current.AjaxCallArgument);
}

}
/// <summary>
/// 回调方法
/// </summary>
/// <param name="arg"></param>
protected void AjaxCallBack(string arg)
{
int index = -1;
string methodName="",param="";
object[] paramList = null;
AjaxPro.JavaScriptObject result = null;
MethodInfo method;
//获取方法和参数
if((index = arg.IndexOf("|")) > 1)
{
methodName = arg.Substring(0,index);
param   = arg.Substring(index+1,arg.Length-index-1);
}
else
{
methodName = arg;
}

//获取JavaScriptObject对象
if("{}" != param)
{
result = Convert2JavaScriptObject(param);
}
//反射回调方法
method = this.CurrentPage.GetType().GetMethod(methodName);
if(null == method)throw new System.Reflection.TargetException(string.Format("在{0}中未找到名为:{1}的方法",this.CurrentClass.FullName,methodName));

//参数不为空的方法调用
if(null != result)
{
paramList = new object[result.Keys.Length];
index = 0;

foreach(ParameterInfo info in method.GetParameters())
{
paramList[index] = Deserialize(result[info.Name],info.ParameterType);
}
}
try
{
method.Invoke(this.CurrentPage,paramList);
}
catch(Exception ex)
{
throw ex;
}
}

/// <summary>
/// 反序列化
/// </summary>
/// <param name="script"></param>
/// <param name="type"></param>
/// <returns></returns>
public object Deserialize(string script,System.Type type)
{
object obj = null;
try
{
obj = AjaxPro.JavaScriptDeserializer.DeserializeFromJson(script,type);
}
catch(Exception ex)
{
throw ex;
}
return obj;
}
public object Deserialize(AjaxPro.IJavaScriptObject o,System.Type type)
{
object obj = null;
try
{
obj = AjaxPro.JavaScriptDeserializer.Deserialize(o,type);
}
catch(Exception ex)
{
throw ex;
}
return obj;
}

/// <summary>
/// 反序列化为JavaScriptObject对象
/// </summary>
/// <param name="script"></param>
/// <returns></returns>
public AjaxPro.JavaScriptObject Convert2JavaScriptObject(string script)
{
AjaxPro.JavaScriptObject obj = null;
try
{
obj = (AjaxPro.JavaScriptObject)Deserialize(script,typeof(AjaxPro.JavaScriptObject));
}
catch(Exception ex)
{
throw ex;
}
return obj;
}

/// <summary>
/// 序列化为字符串
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public string Serialize(object o)
{
string result = "";
try
{
result = AjaxPro.JavaScriptSerializer.Serialize(o);
}
catch(Exception ex)
{
throw ex;
}
return result;
}

/// <summary>
/// 构建注册方法的回调脚本
/// </summary>
/// <param name="methodInfo"></param>
protected void BuilderMethodScript(MethodInfo methodInfo)
{
System.Reflection.ParameterInfo[] param = methodInfo.GetParameters();
string[] args = null;
string[] argsContent = null;

if(null != param)
{
args = new string[param.Length];
argsContent = new string[param.Length];
for(int i=0;i<param.Length;i++)
{
args
= param.Name;
argsContent
= string.Format("\"{0}\":{0}",param.Name);
}
}
//暂时不实现回调方法返回结果
//   if(null == args)
//   {
//   this.ScriptBulilder.Append("{0} : function(){\r\n return Object.invoke(\"{0}\",'');},\r\n",methodInfo.Name);
//   }
//   else
//   {
//  
//   this.ScriptBulilder.Append("{0} : function(){\r\n return Object.invoke(\"{0}\",{1});},\r\n",methodInfo.Name,System.String.Join(", ",argsContent));
//   }
if(null == args)
{
this.ScriptBulilder.Append(string.Format("{0} : function(){\r\n",methodInfo.Name));
this.ScriptBulilder.Append(string.Format(" Object.invoke(\"{0}\",'');},\r\n",methodInfo.Name));
}
else
{

this.ScriptBulilder.Append(string.Format("{0} : function({1})",methodInfo.Name,System.String.Join(",",args)));
this.ScriptBulilder.Append("{\r\n");
this.ScriptBulilder.Append(string.Format(" Object.invoke(\"{0}\",{1});",methodInfo.Name,"{" + System.String.Join(", ",argsContent) + "}"));
this.ScriptBulilder.Append("},\r\n");
}

}
/// <summary>
/// 构建命名空间的声明脚本
/// </summary>
protected void BuilderNameSpaceScript()
{
string[] nameSpace = this.CurrentClass.Namespace.Split('.');
string preName   = "";
foreach(string name in nameSpace)
{
preName = ("" == preName)?name:(preName + "." + name);
this.ScriptBulilder.Append(string.Format("if(typeof({0}) == \"undefined\"){0} = ",preName));
this.ScriptBulilder.Append("{};\r\n");
}
this.ScriptBulilder.Append(string.Format("{0}_class = function()",this.CurrentClass.FullName));
this.ScriptBulilder.Append("{};\r\n");
}
/// <summary>
/// 获取注册后台回调方法
/// </summary>
/// <returns></returns>
protected IList GetMethodsByClass()
{
IList list = new ArrayList();
foreach(MethodInfo info in this.CurrentClass.GetMethods())
{
object[] attributes = info.GetCustomAttributes(typeof(AjaxMethod),false);
if(null == attributes || 0 == attributes.Length)continue;
list.Add(info);
}
return list;
}
#endregion
}

[System.AttributeUsage(System.AttributeTargets.Method)]
public class AjaxMethod : System.Attribute
{
public AjaxMethod()
{
}
}
}

Demo及源码下载

posted on 2007-08-27 23:17  Losesoul  阅读(1584)  评论(1编辑  收藏  举报

导航