其實做這麼個東西沒什麼具體用途,只是在看到這個帖子和這篇BLOG後來了興趣,突發其想來試試能不能做個在線的編譯器,順便也研究下AJax和反射;
AJax是看很長時間了,比較關注微軟的開發包Atlas的動態,也有很多資源:
·MSDN的Atlas 網站
·ASP.Net "Atlas" 官方網站
·ASP.Net "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>
2.在<system.web></system.web>節內添加: <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;
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);
}
}
這裡說明幾個郁悶的問題,不知道是我程序的問題,還是ajaxpro的問題,編輯的代碼字符串居然在傳到服務器端時會把+號去掉,弄得我只好在JS中事先把它替為#,搞的不倫不類的,哪天一定要好好看看AJaxpro的實現代碼,揪出原因來看看!
下面是小個運行效果圖:
以上代碼下載
AJaxPro下載