结合AJAX和反射Refrection,实现页面无刷执行函数体
其实做这么个东西没什么具体用途,只是在看到这个帖子和这篇BLOG后来了兴趣,突发其想来试试能不能做个在线的编译器,顺便也研究下ajax和反射;
ajax是看很长时间了,比较关注微软的开发包Atlas的动态,也有很多资源:
2.在<system.web></system.web>节内添加:
接着,书写反射实现代码,这里还有很多问题没考虑,行家有看法尽管提,下面关于反射的代码基本上偷自ninputer,作了点改动,希望不要引起原作者的非议
再接着实现中间层,很简单的调用
最后就是页面端的两小句代码,和一个js文件了
1.在页面的page_load添加这句就行了
这里说明几个郁闷的问题,不知道是我程序的问题,还是ajaxpro的问题,编辑的代码字符串居然在传到服务器端时会把+号去掉,弄得我只好在js中事先把它替为#,搞的不伦不类的,哪天一定要好好看看ajaxpro的实现代码,揪出原因来看看!
下面是小个运行效果图:
以上代码下载
AjaxPro下载
ajax是看很长时间了,比较关注微软的开发包Atlas的动态,也有很多资源:
·Atlas 快速入门教程
以上几个连接来自思归 的blog,看来他也很关心这项技术;
前面好长一段时间,出现了一个ajax的开发包,在作者的blog上经常能看到这个开发包的动态,一直有心要将其搞到项目上去试试,以来对这个技术还是不很明白,还有就是javascript不是很熟,而且据说开发效率也不高,不敢冒险,这次处在两个项目的空闲期,正好好来看看了;
废话说了不少,还是来看看实现吧:
首先,配置web.config
1.在<configuration></configuration>节内添加如下代码:
<configSections>
<sectionGroup name="ajaxNet">
<section name="ajaxSettings" type="AjaxPro.AjaxSettingsSectionHandler,AjaxPro" />
</sectionGroup>
</configSections>
<ajaxNet>
<ajaxSettings>
<!--
<encryption cryptType="AjaxProSample.SampleCryptProvider, AjaxProSample" keyType="AjaxProSample.SampleKeyProvider, AjaxProSample" />
<token enabled="true" />
-->
<urlNamespaceMappings>
<add namespace="AjaxReflection.AjaxReflect,AjaxReflection" path="MyPath" />
</urlNamespaceMappings>
</ajaxSettings>
</ajaxNet>
<sectionGroup name="ajaxNet">
<section name="ajaxSettings" type="AjaxPro.AjaxSettingsSectionHandler,AjaxPro" />
</sectionGroup>
</configSections>
<ajaxNet>
<ajaxSettings>
<!--
<encryption cryptType="AjaxProSample.SampleCryptProvider, AjaxProSample" keyType="AjaxProSample.SampleKeyProvider, AjaxProSample" />
<token enabled="true" />
-->
<urlNamespaceMappings>
<add namespace="AjaxReflection.AjaxReflect,AjaxReflection" path="MyPath" />
</urlNamespaceMappings>
</ajaxSettings>
</ajaxNet>
2.在<system.web></system.web>节内添加:
<httpHandlers>
<add verb="*" path="AjaxPro/*.ashx" type="AjaxPro.AjaxHandlerFactory,AjaxPro" />
</httpHandlers>
<add verb="*" path="AjaxPro/*.ashx" type="AjaxPro.AjaxHandlerFactory,AjaxPro" />
</httpHandlers>
接着,书写反射实现代码,这里还有很多问题没考虑,行家有看法尽管提,下面关于反射的代码基本上偷自ninputer,作了点改动,希望不要引起原作者的非议
using System;
using System.Text;
using Microsoft.CSharp;
using System.Reflection;
using System.Reflection.Emit;
using System.CodeDom.Compiler;
using System.Threading;
namespace AjaxReflection
{
/// <summary>
/// ReflectionMethod 的摘要说明。
/// </summary>
public sealed class ReflectionMethod
{
private static CSharpCodeProvider comp = new CSharpCodeProvider();
private static CompilerParameters cp = new CompilerParameters();
private static MethodInfo mi;
/// <summary>
/// 执行函数取得结果
/// </summary>
/// <param name="MethodName">函数名</param>
/// <param name="MethodCode">代码段</param>
/// <returns></returns>
public static object ExecuteMethod(string MethodName,string MethodCode)
{
StringBuilder sb = new StringBuilder();
sb.Append("using System;\t\n");
sb.Append("namespace NsReflection{\t\n");
sb.Append("public sealed class Class"+MethodName+"{\t\n");
sb.Append("public static object "+MethodName+"(){\t\n");
sb.Append(MethodCode);
sb.Append("}\t\n}\t\n}\t\n");
cp.ReferencedAssemblies.Add("System.dll");
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
CompilerResults cr = comp.CreateCompiler().CompileAssemblyFromSource(cp,sb.ToString());
CompilerErrorCollection cec = cr.Errors;
if (cec.HasErrors)
{
//throw new ArgumentOutOfRangeException("MethodName:MethodCode","所给定的代码["+sb.ToString()+"]无法通过编译,请检查并修改后重试!");
string strError = string.Empty;
foreach (CompilerError ce in cec)
{
strError += "代码在编译过程中出现如下错误:"+ce.ErrorText+ce.ToString()+"错误所在行"+ce.Line.ToString();
}
return strError;
}
else
{
Assembly a = cr.CompiledAssembly;
Type t = a.GetType("NsReflection.Class"+MethodName,true,true);
mi = t.GetMethod(MethodName, BindingFlags.Static | BindingFlags.Public);
return mi.Invoke(null, new object[0]);
}
}
}
}
using System.Text;
using Microsoft.CSharp;
using System.Reflection;
using System.Reflection.Emit;
using System.CodeDom.Compiler;
using System.Threading;
namespace AjaxReflection
{
/// <summary>
/// ReflectionMethod 的摘要说明。
/// </summary>
public sealed class ReflectionMethod
{
private static CSharpCodeProvider comp = new CSharpCodeProvider();
private static CompilerParameters cp = new CompilerParameters();
private static MethodInfo mi;
/// <summary>
/// 执行函数取得结果
/// </summary>
/// <param name="MethodName">函数名</param>
/// <param name="MethodCode">代码段</param>
/// <returns></returns>
public static object ExecuteMethod(string MethodName,string MethodCode)
{
StringBuilder sb = new StringBuilder();
sb.Append("using System;\t\n");
sb.Append("namespace NsReflection{\t\n");
sb.Append("public sealed class Class"+MethodName+"{\t\n");
sb.Append("public static object "+MethodName+"(){\t\n");
sb.Append(MethodCode);
sb.Append("}\t\n}\t\n}\t\n");
cp.ReferencedAssemblies.Add("System.dll");
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
CompilerResults cr = comp.CreateCompiler().CompileAssemblyFromSource(cp,sb.ToString());
CompilerErrorCollection cec = cr.Errors;
if (cec.HasErrors)
{
//throw new ArgumentOutOfRangeException("MethodName:MethodCode","所给定的代码["+sb.ToString()+"]无法通过编译,请检查并修改后重试!");
string strError = string.Empty;
foreach (CompilerError ce in cec)
{
strError += "代码在编译过程中出现如下错误:"+ce.ErrorText+ce.ToString()+"错误所在行"+ce.Line.ToString();
}
return strError;
}
else
{
Assembly a = cr.CompiledAssembly;
Type t = a.GetType("NsReflection.Class"+MethodName,true,true);
mi = t.GetMethod(MethodName, BindingFlags.Static | BindingFlags.Public);
return mi.Invoke(null, new object[0]);
}
}
}
}
再接着实现中间层,很简单的调用
using System;
namespace AjaxReflection
{
/// <summary>
/// AjaxMethod 的摘要说明。
/// </summary>
public class AjaxMethodRef
{
[AjaxPro.AjaxMethod]
public string Execute(string code)
{
code = code.Replace("#","+");
object oResult = ReflectionMethod.ExecuteMethod("MyTest",code);
return String.Format("返回结果类型为;{0};\t\n值为;{1}",oResult.GetType().ToString(),oResult.ToString());
}
}
}
namespace AjaxReflection
{
/// <summary>
/// AjaxMethod 的摘要说明。
/// </summary>
public class AjaxMethodRef
{
[AjaxPro.AjaxMethod]
public string Execute(string code)
{
code = code.Replace("#","+");
object oResult = ReflectionMethod.ExecuteMethod("MyTest",code);
return String.Format("返回结果类型为;{0};\t\n值为;{1}",oResult.GetType().ToString(),oResult.ToString());
}
}
}
最后就是页面端的两小句代码,和一个js文件了
1.在页面的page_load添加这句就行了
AjaxPro.Utility.RegisterTypeForAjax(typeof(AjaxMethodRef));
2.将下面的javascript脚本存为AjaxJScript.js var Code;
function GetExecuteResult()
{
Code = document.getElementById("tbCode").value;
Replace("+","#");
alert(AjaxReflection.AjaxMethodRef.Execute(Code).value);
}
function Replace(oldSub,newSub)
{
var index = Code.indexOf(oldSub);
if (index==-1)
{
return Code;
}
else
{
Code = Code.substring(0,index)+newSub+Code.substring(index+1,Code.length);
Replace(oldSub,newSub);
}
}
function GetExecuteResult()
{
Code = document.getElementById("tbCode").value;
Replace("+","#");
alert(AjaxReflection.AjaxMethodRef.Execute(Code).value);
}
function Replace(oldSub,newSub)
{
var index = Code.indexOf(oldSub);
if (index==-1)
{
return Code;
}
else
{
Code = Code.substring(0,index)+newSub+Code.substring(index+1,Code.length);
Replace(oldSub,newSub);
}
}
这里说明几个郁闷的问题,不知道是我程序的问题,还是ajaxpro的问题,编辑的代码字符串居然在传到服务器端时会把+号去掉,弄得我只好在js中事先把它替为#,搞的不伦不类的,哪天一定要好好看看ajaxpro的实现代码,揪出原因来看看!
下面是小个运行效果图:
以上代码下载
AjaxPro下载