1. 回顧
上一篇文章,將webconfig中的設定介紹了下,為我們在擷取資料處理的時候,打好了紮實的基礎,現在我們我們來詳細講講“RemoteCallHandler”這個類。
2. 介紹
RemoteCallHandler類,是我們在webconfig中定義了,當Post訪問。Xyz尾碼的檔案時,網站程式自己調用的,前面也說過,此類繼承了兩個類一個是IHttpHandler,一個是IRequiresSessionState;
IRequiresSessionState類:
指定目標 HTTP 處理常式需要對工作階段狀態值具有讀寫訪問權。這是一個標記介面,沒有任何方法。在自訂 HTTP 處理常式中實現 IRequiresSessionState 介面,以確定處理常式是否需要對工作階段狀態值具有讀寫訪問權。
IHttpHandler類:
定義 ASP.NET 為使用自訂 HTTP 處理常式同步處理 HTTP Web 請求而實現的協定。可以用任何符合Common Language Specification (CLS) 的語言編寫自訂 HTTP 處理常式來處理特定的、預定義類型的 HTTP 要求。響應這些特定請求的是在 HttpHandler 類中定義的可執行代碼,而不是常規的 ASP 或 ASP.NET網頁。HTTP 處理常式向您提供一種方法,使您可以與 IIS Web 服務器的低層級的請求和響應服務互動,同時提供極其類似於 ISAPI 擴充但編程模型較為簡單的功能。如果您的處理常式將訪問工作階段狀態值,它必須實現 IRequiresSessionState 介面(不包含任何方法的標記介面)。
從MSDN介紹可得到,我們在自訂IHttpHandler的時候必須要繼承這兩個類,為什麼要使用此類,因為我們要擷取網站請求的資料,然後根據捕獲訪問的資料,對資料進行相關的調用與設定。
3. RemoteCallHandler類詳細
1. using System;
2. using System.Reflection;
3. using System.Web;
4. using System.Web.SessionState;
5.
6. namespace Better.Web
7. {
8. //此處繼承IhttpHandler與IRequiresSessionState
9. public class RemoteCallHandler : IHttpHandler, IRequiresSessionState
10. {
11.
12. #region IHttpHandler 成員
13. //實現IhttpHandler裡面的IsResuable屬性
14. public bool IsReusable { get { return false; } }
15.
16. //實現IHttpHandler中的ProcessRequest方法
17. public void ProcessRequest(HttpContext context)
18. {
19. //擷取當前請求對象
20. HttpRequest request = context.Request;
21. //擷取當前發送對象
22. HttpResponse response = context.Response;
23. //擷取請求的頭
24. string invokeType = request.Headers["RemoteInvoke"];
25. //如果請求的頭位空,直接拋出異常
26. if (string.IsNullOrEmpty(invokeType)) { throw new MissingInvokeTypeException(); }
27. //判斷當前的指定頭的值是否是正確的
28. if (invokeType.Equals("MethodInvoke"))
29. {
30. try
31. {
32. //如果請求符合,啟動並執行方法,列印在頁面上
33. response.Write(MethodInvoke(request));
34. }
35. catch (Exception ex)
36. {
37. /*當報錯時,處理的資訊,將資訊構造成json格式*/
38. string message = (ex.InnerException == null ? ex.Message : ex.InnerException.Message);
39. response.StatusCode = 500;
40. response.Write("{");
41. response.Write(string.Format("\"code\":{0},\"message\":\"{1}\"", 500, message));
42. response.Write("}");
43. }
44. finally
45. {
46. try
47. {
48. response.End();
49. }
50. catch { }
51. }
52. }
53. }
54. #endregion
55. //真實的處理函數
56. private string MethodInvoke(HttpRequest request)
57. {
58. /*判斷請求是否為空白*/
59. if (request == null) { throw new ArgumentNullException("request"); }
60. /*擷取反射對象,判斷request.Headers["Assembly"]是否為null 如果為null直接返回Null 字元串*/
61. string assembly = request.Headers["Assembly"] ?? "";
62. /*擷取操作類型*/
63. string typeName = request.Headers["TargetType"];
64. /*擷取要調用的後台函數名*/
65. string methodName = request.Headers["CallingMethod"];
66. /*判斷操作類型名是否為空白*/
67. if (string.IsNullOrEmpty(typeName)) { throw new MissingCallingTypeException(); }
68. /*判斷調用的後台函數名是否為空白*/
69. if (string.IsNullOrEmpty(methodName)) { throw new MissingCallingMethodException(); }
70. /* 擷取遠程調用的目標類型。*/
71. Type type = Type.GetType(typeName + (string.IsNullOrEmpty(assembly) ? "" : "," + assembly));
72. if (type != null)
73. {
74. /* 擷取遠程調用的目標方法。*/
75. MethodInfo mi = type.GetMethod(methodName);
76. if (mi != null)
77. {
78. /* 擷取調用參數。*/
79. object[] arguments = null;
80. ParameterInfo[] pis = mi.GetParameters();
81. if (pis.Length > 0)
82. {
83. arguments = new object[pis.Length];
84. for (int i = 0; i < pis.Length; i++)
85. {
86. arguments[i] = Convert.ChangeType(request.Form[i], pis[i].ParameterType);
87. }
88. }
89. /* 判斷調用的方法是否靜態方法。
l 如果是靜態方法,則方法調用不需建立類執行個體。*/
90. object inst = mi.IsStatic ? null : Activator.CreateInstance(type, true);
91. if (mi.ReturnType.Name == "Void")
92. {
93. mi.Invoke(null, arguments);
94. return "";
95. }
96. else
97. {
98. return mi.Invoke(null, arguments).ToString();
99. }
100.}
101.throw new GetMethodFailedException(typeName, methodName);
102.}
103.throw new GetTypeFailedException(typeName);
104.}
105.}
106./// <summary>
107./// 遠程調用缺少調用類型時引發的異常。
108./// </summary>
109.[Serializable]
110.public class MissingInvokeTypeException : Exception
111.{
112. public MissingInvokeTypeException() : base("缺少調用類型。") { }
113.}
114./// <summary>
115./// 遠程調用缺少目標類型時引發的異常。
116./// </summary>
117.[Serializable]
118.public class MissingCallingTypeException : Exception
119.{
120. public MissingCallingTypeException() : base("遠程調用缺少目標類型。") { }
121.}
122./// <summary>
123./// 遠程調用缺少目標方法時引發的異常。
124./// </summary>
125.[Serializable]
126.public class MissingCallingMethodException : Exception
127.{
128. public MissingCallingMethodException() : base("遠程調用缺少目標方法。") { }
129.}
130./// <summary>
131./// 遠程調用載入類型失敗時引發的異常。
132./// </summary>
133.[Serializable]
134.public class GetTypeFailedException : Exception
135.{
136. public GetTypeFailedException() : base("載入類型失敗。") { }
137. public GetTypeFailedException(string typeName) : base(string.Format("載入類型 \"{0}\" 失敗。", typeName)) { }
138.}
139./// <summary>
140./// 遠程調用擷取目標方法失敗時引發的異常。
141./// </summary>
142.[Serializable]
143.public class GetMethodFailedException : Exception
144.{
145. public GetMethodFailedException() : base("擷取方法失敗。") { }
146. public GetMethodFailedException(string methodName) : base(string.Format("擷取 \"{0}\" 方法失敗。", methodName)) { }
147. public GetMethodFailedException(string typeName, string methodName) : base(string.Format("擷取類型 \"{0}\" 的 \"{1}\" 方法失敗。", typeName, methodName)) { }
148.}
149./// <summary>
150./// 遠程調用失敗時引發的異常。
151./// </summary>
152.[Serializable]
153.public class RemoteInvokeFailedException : Exception
154.{
155. public RemoteInvokeFailedException() : base("遠程調用失敗。") { }
156. public RemoteInvokeFailedException(string typeName, string methodName) : base(string.Format("遠程調用方法 \"{0}.{1}\" 失敗。", typeName, methodName)) { }
157.}
158.}