通過前面3天的學習,我想你們應該對SOA的架構有了初步的瞭解,其實 SOA與三層架構並不衝突,而是三層架構的升級版。linux
來看下傳統的三層架構! 一共能夠分爲4個層: 模型層(無關緊要),客戶端,服務端,公共層。web
咱們在原有的三層架構的基礎上,咱們增長一個服務中轉層! 而後客戶端 經過 調用 服務中轉,而後在調用 服務層,由於客戶端能夠有多個,能夠是安卓,能夠是IOS,ajax
能夠是電腦,能夠是linux, 由於這個無論是什麼樣的語言和系統,她們都支持JSON以及xml。正則表達式
以下圖:(common:公共層,DataServer服務層,wcf服務中轉層,webClient web 客戶端)sql
接下咱們來看下關鍵代碼處: (下面有對應的源代碼下載)數據庫
來看下如何經過 通用查詢 來查詢數據的流程:json
首先 前臺經過 ajax 的訪問咱們的 svc 文件,來進行訪問:數組
1.這裏須要注意的是, ajax 使用 get 和post 時,傳入json的格式是不同的。架構
var s = '{ "aa":"' + $("#txt_data").val() + '"}';
$.postwcf = function (database, method, //操做的方法名字 sql, //sql語句或者傳入的 數據 success, //執行成功所返回的方法 err) { //執行失敗所返回的方法 var url = $.getrooturl() + "/WebService.svc/operate"; var data; if (sql.indexOf("{")>0 && sql.indexOf('"')>0 && sql.indexOf("}")>0) { data = { "database": database, "method": method, "sql": JSON.stringify(sql), }; } else { data = { "database": database, "method": method, "sql":sql, }; } $.ajax({ url: url, contentType: "application/json;charset=utf-8", data: JSON.stringify(data), type: "post", success: function (data) { success(data); }, error: function (error) { err(error); } }); }
上面這個 post的方法, json 格式須要 ' {"aa":"123"} '
西面這個是get的方法,json格式爲 {"aa":"123"}app
很顯然,一個傳入json格式是須要引號才能辨認,一個這不須要引號進行辨認。
$.getwcf = function (database, method, //操做的方法名字 sql, //sql語句或者傳入的 數據 success, //執行成功所返回的方法 err) { //執行失敗所返回的方法 var url = $.getrooturl() + "/WebService.svc/operateByGet"; var data; if (sql.indexOf("{") > 0 && sql.indexOf('"') > 0 && sql.indexOf("}") > 0) { data = { "database": database, "method": method, "sql": JSON.stringify(sql), }; } else { data = { "database": database, "method": method, "sql": sql, }; } $.ajax({ url: url, contentType: "application/json;charset=utf-8", data:data, type: "get", success: function (data) { success(data); }, error: function (error) { err(error); } }); }
2.另外咱們的後臺,對應的 契約,也就是接口須要注意的就是:
咱們能夠看到,咱們能夠看到咱們寫了2個接口,一個是須要用 POST
調用的,一個是須要用get 調用的,其實2個所執行的方法都是同樣的。WebInvoke對應的是post,WebGet對應的是get的調用。
[ServiceContract] interface ISqlServer { /// <summary> /// 這裏指所執行的操做(其中保證 sql 語句) /// </summary> /// <param name="database">數據庫的名字</param> /// <param name="operate">所執行的操做,select ,insert,delete</param> /// <param name="method">方法名</param> /// <param name="sql">sql語句</param> /// <returns>返回數據類型爲json格式</returns> [OperationContract] [WebInvoke(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] string operate(string database, string method, string sql); [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] string operateByGet(string database, string method, string sql); }
3.實現原有類的方法擴展,例如 在datatable的基礎上 增長一個 .toJson的方法:如何來寫呢?
public static class Extend { /// <summary> /// 這是將 datatable轉化爲json的方法 /// </summary> /// <param name="pData"></param> /// <returns></returns> public static string ToJson(this DataTable pData) { //這裏就能夠來寫你的代碼了 }
注意 必須 是靜態類中的靜態方法,參數中 帶有 this 關鍵字
4.實現一種反射可以 經過 指定 命名空間,類名,方法名, 參數,就可以執行對應的 方法(靜態 與非靜態都能執行)
/// <summary> /// 根據字符執行該方法 /// </summary> /// <param name="path">命名空間</param> /// <param name="className">類名</param> /// <param name="MethodName">方法名</param> /// <param name="dic">傳入的參數</param> /// <returns>返回object類型</returns> public static object Execute(string path, string className, string MethodName, Dictionary<string,object> dic) { object[] parameters=new object[1]; parameters[0] = dic; //動態從程序集中查找所須要的類並使用系統激活器建立實例最後獲取它的Type Type type = Assembly.Load(path).CreateInstance(path + "." + className).GetType(); //定義參數的個數,順序以及類型的存儲空間; Type[] parametersLength; if (parameters != null) //表示方法的參數不爲空才執行 { parametersLength = new Type[parameters.Length]; int i = 0; foreach (object obj in parameters) { parametersLength.SetValue(obj.GetType(), i); i++; } } else { //沒有參數就爲空 parametersLength = new Type[0]; } //而後咱們來查找制定的方法 MethodInfo methodinfo = type.GetMethod(MethodName, parametersLength); if (methodinfo.IsStatic) { return methodinfo.Invoke(null, parameters); } else { object obj = Activator.CreateInstance(type); //表示不屬於靜態方法的調用 return methodinfo.Invoke(obj, parameters); } }
注意 看到 執行方法 時 要 分 靜態 與非靜態,靜態時 不用實例化對象,不然就得 實例化對象。
5.另外我還附上, json 與字典方法的相互轉換:
/// <summary> /// 這是將 json 轉成 dictionary 的方法 /// </summary> /// <param name="JsonData"></param> /// <returns></returns> public static Dictionary<string, object> ToDictionary(this string JsonData) { object Data = null; Dictionary<string, object> Dic = new Dictionary<string, object>(); if (JsonData.StartsWith("[")) { //若是目標直接就爲數組類型,則將會直接輸出一個Key爲List的List<Dictionary<string, object>>集合 21. //使用示例 List<Dictionary<string, object>> ListDic = (List<Dictionary<string, object>>)Dic["List"]; List<Dictionary<string, object>> List = new List<Dictionary<string, object>>(); MatchCollection ListMatch = Regex.Matches(JsonData, @"{[\s\S]+?}");//使用正則表達式匹配出JSON數組 24. foreach (Match ListItem in ListMatch) { List.Add(ToDictionary(ListItem.ToString()));//遞歸調用 } Data = List; Dic.Add("List", Data); } else { MatchCollection Match = Regex.Matches(JsonData, @"""(.+?)"": {0,1}(\[[\s\S]+?\]|null|"".+?""|-{0,1}\d*)");//使用正則表達式匹配出JSON數據中的鍵與值 foreach (Match item in Match) { if (item.Groups[2].ToString().StartsWith("[")) { //若是目標是數組,將會輸出一個Key爲當前Json的List<Dictionary<string, object>>集合 List<Dictionary<string, object>> ListDic = (List<Dictionary<string, object>>)Dic["Json中的Key"]; List<Dictionary<string, object>> List = new List<Dictionary<string, object>>(); MatchCollection ListMatch = Regex.Matches(item.Groups[2].ToString(), @"{[\s\S]+?}");//使用正則表達式匹配出JSON數組 foreach (Match ListItem in ListMatch) { List.Add(ToDictionary(ListItem.ToString()));//遞歸調用 } Data = List; } else if (item.Groups[2].ToString().ToLower() == "null") Data = null;//若是數據爲null(字符串類型),直接轉換成null else Data = item.Groups[2].ToString(); //數據爲數字、字符串中的一類,直接寫入 Dic.Add(item.Groups[1].ToString(), Data); } } return Dic; }
6.另外其餘的 東西,在前面的章節中有講過,不過wcf的原理看以簡單的介紹下:
首先,經過ajax 請求 wcf 服務,而後進入到wcf服務後臺,驗證該方法名是否存在,若是 存在 則直接執行該方法名,
不然經過 反射 尋找到該方法執行。返回string的json格式。直接傳輸到前臺。這樣就能夠達到 前臺與 後臺直接進行交互,而去掉了繁雜的
C#調用後臺的方法。
另外附上VS2012的源代碼:
http://files.cnblogs.com/files/liujing379069296/MySOA.rar
(說明:只須要修改web.config 中的鏈接字符串,而後寫入 你對應數據庫的sql語句就可使用了)