1. Review
In the previous article, we introduced the settings in webconfig to lay a solid foundation for data processing. Now let's talk about the RemoteCallHandler class in detail.
2. Introduction
The RemoteCallHandler class is defined in webconfig when Post is accessed. When a file with the Xyz suffix is called by the website program, as mentioned earlier, this class inherits two classes: IHttpHandler and IRequiresSessionState;
IRequiresSessionState class:
Specify the target HTTP handler to have read and write access to the session status value. This is a tag interface and there is no way. Implement the IRequiresSessionState interface in the Custom HTTP handler to determine whether the handler needs to have read and write access to the session status value.
IHttpHandler class:
Defines the Protocol implemented by ASP. NET to use a custom HTTP handler to synchronously process HTTP Web requests. You can use any language that complies with common language standards (CLS) to write custom HTTP handlers to process specific and predefined types of HTTP requests. The executable code defined in the HttpHandler class is used to respond to these specific requests, rather than the conventional ASP or ASP. NET webpage. The HTTP processing program provides you with a way to interact with low-level requests and Response Services of the IIS Web server. It also provides functions that are very similar to ISAPI extensions but simple programming models. If your handler accesses the session status value, it must implement the IRequiresSessionState interface (the flag interface that does not contain any methods ).
According to the MSDN introduction, we must inherit these two classes when customizing IHttpHandler. Why should we use this class because we need to obtain the data requested by the website, then, call and set the data based on the captured access data.
3. RemoteCallHandler class details
1. using System;
2. using System. Reflection;
3. using System. Web;
4. using System. Web. SessionState;
5.
6. namespace Better. Web
7 .{
8. // The IhttpHandler and IRequiresSessionState are inherited here.
9. public class RemoteCallHandler: IHttpHandler, IRequiresSessionState
10 .{
11.
12. # region IHttpHandler Member
13. // implement the IsResuable attribute in IhttpHandler
14. public bool IsReusable {get {return false ;}}
15.
16. // implement the ProcessRequest method in IHttpHandler
17. public void ProcessRequest (HttpContext context)
18 .{
19. // get the current request object
20. HttpRequest request = context. Request;
21. // get the current sending object
22. HttpResponse response = context. Response;
23. // obtain the Request Header
24. string invokeType = request. Headers ["RemoteInvoke"];
25. // if the request header is empty, an exception is thrown directly.
26. if (string. IsNullOrEmpty (invokeType) {throw new MissingInvokeTypeException ();}
27. // determine whether the current value of the specified header is correct
28. if (invokeType. Equals ("MethodInvoke "))
29 .{
30. try
31 .{
32. // if the request matches, the running method is printed on the page.
33. response. Write (MethodInvoke (request ));
34 .}
35. catch (Exception ex)
36 .{
37./* When an error is reported, the processed information is constructed into json format */
38. string message = (ex. InnerException = null? Ex. Message: ex. InnerException. Message );
39. response. statuscodes = 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. // real processing functions
56. private string MethodInvoke (HttpRequest request)
57 .{
58./* determine whether the request is blank */
59. if (request = null) {throw new ArgumentNullException ("request ");}
60./* obtain the reflection object and determine whether request. Headers ["Assembly"] is null. If it is null, an empty string is directly returned */
61. string assembly = request. Headers ["Assembly"]? "";
62./* Get operation type */
63. string typeName = request. Headers ["TargetType"];
64./* obtain the name of the background function to be called */
65. string methodName = request. Headers ["CallingMethod"];
66./* determine whether the operation type name is null */
67. if (string. IsNullOrEmpty (typeName) {throw new MissingCallingTypeException ();}
68./* determine whether the called background function name is blank */
69. if (string. IsNullOrEmpty (methodName) {throw new MissingCallingMethodException ();}
70./* obtain the target type of the Remote Call. */
71. Type type = Type. GetType (typeName + (string. IsNullOrEmpty (assembly )? "": "," + Assembly ));
72. if (type! = Null)
73 .{
74./* obtain the target method of Remote Call. */
75. MethodInfo mi = type. GetMethod (methodName );
76. if (mi! = Null)
77 .{
78./* obtain the call parameters. */
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./* determine whether the called method is a static method.
L if it is a static method, you do not need to create a class instance for method calling. */
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. // the exception that is thrown when the call type is missing for a remote call.
108. /// </summary>
109. [Serializable]
110. public class MissingInvokeTypeException: Exception
111 .{
112. public MissingInvokeTypeException (): base ("the call type is missing. "){}
113 .}
114. // <summary>
115. // exception thrown when the target type is missing for remote calls.
116. /// </summary>
117. [Serializable]
118. public class MissingCallingTypeException: Exception
119 .{
120. public MissingCallingTypeException (): base ("the target type is missing for remote calls. "){}
121 .}
122. // <summary>
123. // the exception that is thrown when the target method is missing for a remote call.
124. /// </summary>
125. [Serializable]
126. public class MissingCallingMethodException: Exception
127 .{
128. public MissingCallingMethodException (): base ("the target method is missing for remote calls. "){}
129 .}
130. // <summary>
131. // exception thrown when the remote call fails to load the type.
132. /// </summary>
133. [Serializable]
134. public class GetTypeFailedException: Exception
135 .{
136. public GetTypeFailedException (): base ("loading type failed. "){}
137. public GetTypeFailedException (string typeName): base (string. Format ("loading Type \" {0} \ "failed. ", TypeName )){}
138 .}
139. // <summary>
140. // exception thrown when the remote call fails to obtain the target method.
141. /// </summary>
142. [Serializable]
143. public class GetMethodFailedException: Exception
144 .{
145. public GetMethodFailedException (): base ("failed to obtain method. "){}
146. public GetMethodFailedException (string methodName): base (string. Format ("Get \" {0} \ "method failed. ", MethodName )){}
147. public GetMethodFailedException (string typeName, string methodName): base (string. Format ("Get Type \" {0} \ "\" {1} \ "method failed. ", TypeName, methodName )){}
148 .}
149. // <summary>
150. // the exception that is thrown when the remote call fails.
151. /// </summary>
152. [Serializable]
153. public class RemoteInvokeFailedException: Exception
154 .{
155. public RemoteInvokeFailedException (): base ("Remote Call failed. "){}
156. public RemoteInvokeFailedException (string typeName, string methodName): base (string. Format ("Remote Call Method \" {0}. {1} \ "failed. ", TypeName, methodName )){}
157 .}
158 .}