In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Write an example analysis of lightweight ajax component 02Mel-Analysis AjaxPro. In view of this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.
I. the use of ajaxpro
Let's first look at how this component is used.
1. Register for AjaxHandlerFactory
Configure the following in web.config:
To put it simply, the requested url is processed by AjaxHandlerFactory if it conforms to the ajaxpro/*.ashx format, which is a factory class that implements the IHandlerFactory interface and is used to obtain IHandler handlers. The format of type is: "name control. Class name, assembly name".
two。 Register in the page class Page_Load event
Protected void Page_Load (object sender, EventArgs e) {AjaxPro.Utility.RegisterTypeForAjax (typeof (AjaxProPage));}
We pass the Type of this page object to the ResisterTypoForAjax method, which is used to register the script in the foreground, specifically calling the RegisterClientScriptBlock of the current Page object to register, so there must be one in the .aspx file, otherwise the script will not be able to register. (Type is passed here, which can actually be passed without passing, and this type can also be obtained internally through HttpContext.Current.Handler.GetType (). BaseType)
3. Marking method with AjaxMethod
[AjaxMethod] public List GetList (string input1,string input2) {return new List {input1, input2};}
AjaxMethod is a tag attribute, indicating that this method is used to process ajax requests, which is finally executed through reflection; it has several constructor pairs, and for some data that needs to be cached, you can set the caching time; if our request does not need to use Session, you can set HttpSessionStateRequirement; if the request needs to be asynchronous, such as requesting a time-consuming web service, you can also set the handler to asynchronous.
The return value of a method can be a simple type or a complex type; for example, the collection type obtained in the foreground is an array.
4. Foreground call
The configuration and use of the background are very simple. Next, let's see how the foreground initiates the request.
Function GetList () {/ / var result = AjaxProNamespace.AjaxProPage.GetList ("a", "b"). Value; / / console.log (result); AjaxProNamespace.AjaxProPage.GetList ("a", "b", function (result) {console.log (result);});}
Here AjaxProNamespace is the namespace where the page class is located, AjaxProPage is the name of the page class, and GetList is the method of the tag. Why can it be written like this? As mentioned earlier, ajaxpro registers the script in the foreground, and it generates the following script based on the information about our page object, so we can call it this way without having to write js or use the jquery library method at all.
If (typeof AjaxProNamespace= = "undefined") AjaxProNamespace= {}; if (typeof AjaxProNamespace.AjaxProPage_class= = "undefined") AjaxProNamespace.AjaxProPage_class= {}; AjaxProNamespace.AjaxProPage_class= function () {}; Object.extend (AjaxProNamespace.AjaxProPage_class.prototype, Object.extend (new AjaxPro.AjaxClass (), {GetList: function (input1, input2) {return this.invoke ("GetList", {"input1": input1, "input2": input2}, this.GetList.getArguments (). Slice (2)) }, url:'/ ajaxpro/AjaxProNamespace.AjaxProPage,TestAjaxProSourceCode.ashx'}); AjaxProNamespace.AjaxProPage = new AjaxProNamespace.AjaxProPage_class ()
The parameters of GetList correspond to the parameters of the background method, and the type must be convertible, otherwise the call will fail. The last parameter is the callback function. The parameter of the callback function is the object that encapsulates the returned result, and its value property is the value returned successfully. For example, the one returned above is an array object. Its error includes information about failures.
Note that what is commented out above is the practice of synchronous requests, which is often not what we want, and I have seen such misuse before.
Second, the principle of ajaxpro processing requests.
Here, we mainly focus on the process of the component processing ajax request, and other auxiliary functions are not introduced.
1. Generate auxiliary scripts
In the Page_Load event, we call AjaxPro.Utility.RegisterTypeForAjax (typeof (AjaxProPage)); to register the required script. We noticed that the following script was introduced on the foreground page:
That is, each page will initiate these requests. These are all .ashx-ending files, but they are actually js code; some of these js are nested within dll as resources, and some are automatically generated, mainly encapsulating ajax request-related methods, and allowing us to use: namespaces. The name of the page class. Mark the method name to call the method in this way. Why use .ashx instead of .js? Because as a resource file within the component, the .js file cannot be requested directly from the outside, while the .ashx can be intercepted and output using Response.Write.
If it is inefficient to generate and send these scripts every time, the internal processing of ajaxpro is to determine the If-None-Math and If-Modified-Since of the request header, and if both are the same as the cache, a 304 status code is returned. Therefore, the client only returns the contents of the file when it requests the server for the first time, and the subsequent ones only return 304 to indicate the use of local cache. We refresh the page to verify this process:
two。 Intercept request
HttpHandler (IHttpHandler) and HttpModule (IHttpModule) are two important components of asp.net, which allow us to easily expand on the basis of asp.net. HttpHandler corresponds to a specific request, such as .ashx, .aspx, etc.; HttpModule is an interceptor that intercepts all requests at an event in the pipeline. To put it simply, in the pipeline, HttpApplication triggers a series of events, and we are registering an event through HttpModule, for example, we can intercept the request before the handler object is generated, and then map to our own handler; it is the HttpHandler that actually processes the request, such as Page to generate the html.
Take the asp.net mvc framework as an example, it is based on the asp.net routing mechanism. The asp.net routing system intercepts the request through a UrlRoutingModule, specifically intercepts the PostResolveRequestCache event, parses the url, encapsulates the corresponding routing data, and finally sends the request to a MvcHandler for processing, and MvcHandler implements the IHttpHandler interface.
We configured this earlier: this indicates that any Post/Get request that ends with an arbitrary name of ajaxpro/ .ashx is left to AjaxPro.AjaxHandlerFactory for processing, which is a handler factory that implements IHandlerFactory to generate a specific IHttpHandler. Several classes that implement IHttpHandler are defined within the component, some are for generating js scripts, and for processing ajax requests, they are mainly divided into two categories: IHttpAsyncHandler and non-asynchronous (IHttpHandler). On the basis of these two categories, the support for the state of Session is divided into three types: Handler that supports reading and writing (implementing the IRequiresSessionState tag interface), Handler that supports read-only (implementing the IReadOnlySessionState tag interface) and Handler that does not support Session. What kind of Handler is generated is judged by AjaxMethod.
The ProcessRequest of IHttpHandler (asynchronous is BeginProcessRequest) is used to execute the request and return the output result. If only one handler is needed, we can also implement IHttpHandler. IHandlerFactory is defined as follows:
Public interface IHttpHandlerFactory {IHttpHandler GetHandler (HttpContext context, string requestType, string url, string pathTranslated); void ReleaseHandler (IHttpHandler handler);}
Therefore, all requests for ajaxpro will conform to the ajaxpro/*.ashx format, and then you can process them in the GetHandler method. The returned result is IHttpHandler;. Take the non-asynchronous state as an example. If we configure a Session, we will generate a Handler that implements IHttpHandler and IRequiresSessionState. If we need a read-only Session, we will generate a Handler; that implements IHttpHandler and IReadOnlySessionState. This information can be obtained from the AjaxMethod tag attributes through reflection. The main code of AjaxHandlerFactory is as follows:
Public IHttpHandler GetHandler (HttpContext context, string requestType, string url, string pathTranslated) {string filename = Path.GetFileNameWithoutExtension (context.Request.Path); Type t = null; Exception typeException = null; bool isInTypesList = false; switch (requestType) {/ / Get request to get the previous four scripts case "GET": switch (filename.ToLower ()) {case "prototype": return new EmbeddedJavaScriptHandler ("prototype"); case "core": return new EmbeddedJavaScriptHandler ("core") Case "ms": return new EmbeddedJavaScriptHandler ("ms"); case "prototype-core": case "core-prototype": return new EmbeddedJavaScriptHandler ("prototype,core"); case "converter": return new ConverterJavaScriptHandler (); default: return new TypeJavaScriptHandler (t);} case "POST": IAjaxProcessor [] p = new IAjaxProcessor [2]; p [0] = new XmlHttpRequestProcessor (context, t); p [1] = new IFrameProcessor (context, t) For (int I = 0; I
< p.Length; i++) { if (p[i].CanHandleRequest) { //获取标记方法的AjaxMethod属性 AjaxMethodAttribute[] ma = (AjaxMethodAttribute[])p[i].AjaxMethod.GetCustomAttributes(typeof(AjaxMethodAttribute), true); bool useAsync = false; HttpSessionStateRequirement sessionReq = HttpSessionStateRequirement.ReadWrite; if (ma.Length >0) {useAsync = ma [0] .UseAsyncProcessing; if (ma [0] .RequireSessionState! = HttpSessionStateRequirement.UseDefault) sessionReq = ma [0] .RequireSessionState;} / 6 kinds of Handler, depending on whether asynchronous, the session status returns the specified Handler switch (sessionReq) {case HttpSessionStateRequirement.Read: if (! useAsync) return new AjaxSyncHttpHandlerSessionReadOnly (p [I]) Else return new AjaxAsyncHttpHandlerSessionReadOnly (p [I]); case HttpSessionStateRequirement.ReadWrite: if (! useAsync) return new AjaxSyncHttpHandlerSession (p [I]); else return new AjaxAsyncHttpHandlerSession (p [I]); case HttpSessionStateRequirement.None: if (! useAsync) return new AjaxSyncHttpHandler (p [I]); else return new AjaxAsyncHttpHandler (p [I]) Default: if (! useAsync) return new AjaxSyncHttpHandlerSession (p [I]); else return new AjaxAsyncHttpHandlerSession (p [I]);}} break;} return null;}
3. Reflection execution method
When you have a Handler that handles this request, you can execute the specified method on its ProcessRequest (asynchronously BeginProcessRequest). To execute a method of a page object, we must know the assembly, namespace, page class name, and method name of the specified page. This seems to fit in front of us: namespaces. Class name. How the method name is called. In order to distinguish it from normal requests and make components sufficiently independent, ajaxpro only intercepts requests that conform to the "ajaxpro/*.ashx format", which means that our ajax requests should also conform to this format. Such as: http://localhost:50712/ajaxpro/AjaxProNamespace.AjaxProPage,TestAjaxProSourceCode.ashx, this format is automatically generated by the foreground script and does not require us to construct it. If you look closely, you will find that AjaxProNamespace.AjaxProPage,TestAjaxProSourceCode is the fully qualified name of the page class: namespace. Class name, assembly name, through which we can generate a concrete Type, and then reflect to get the information. What about the name of the method? Ajaxpro puts it in the http header, which is called X-AjaxPro-Method. With this information, you can reflect the execution method. The core code here is:
Internal void Run () {try {/ / sets the output not to be cached (this is not necessarily what we want) p.Context.Response.Expires = 0; p.Context.Response.Cache.SetCacheability (System.Web.HttpCacheability.NoCache); p.Context.Response.ContentType = p.ContentType; p.Context.Response.ContentEncoding = System.Text.Encoding.UTF8 / / verify ajax request if (! p.IsValidAjaxToken ()) {p.SerializeObject (new System.Security.SecurityException ("The AjaxPro-Token is not valid.")); return;} / / method parameter object array object [] po = null; / / request processing result object res = null; try {/ / get parameter po = p.RetreiveParameters () } catch (Exception ex) {} / / get cache Key string cacheKey = p.Type.FullName + "|" + p.GetType (). Name + "|" + p.AjaxMethod.Name + "|" + p.GetHashCode (); if (p.Context.Cache [cacheKey]! = null) {/ / if cache exists, cache p.Context.Response.AddHeader ("X-" + Constant.AjaxID + "- Cache", "server") is used directly. P.Context.Response.Write (p.Context.Cache [cacheKey]); return;} try {if (p.AjaxMethod.IsStatic) {/ / using reflection to call static method try {res = p.Type.InvokeMember (p.AjaxMethod.Name, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.InvokeMethod, null, null, po) } catch (Exception ex) {}} else {try {/ / create instance object, reflection calls instance method object c = (object) Activator.CreateInstance (p.Type, new object [] {}); if (c! = null) {res = p.AjaxMethod.Invoke (c, po) }} catch (Exception ex) {} catch (Exception ex) {} try {/ / determine whether the result is xml. Set ContentType if (res! = null & & res.GetType () = = typeof (System.Xml.XmlDocument)) {p.Context.Response.ContentType = "text/xml"; p.Context.Response.ContentEncoding = System.Text.Encoding.UTF8 ((System.Xml.XmlDocument) res) .Save (p.Context.Response.OutputStream); return;} string result = null;; System.Text.StringBuilder sb = new System.Text.StringBuilder (); try {result = p.SerializeObject (res) } catch (Exception ex) {} / / if caching is required, write the result to the cache if (p.ServerCacheAttributes.Length > 0) {if (p.ServerCacheAttributes [0] .IsCacheEnabled) {p.Context.Cache.Add (cacheKey, result, null, DateTime.Now.Add (p.ServerCacheAttributes [0] .CacheDuration), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null) } catch (Exception ex) {}} catch (Exception ex) {}}
III. Summary
Let's summarize the core processing flow of ajaxpro, which intercepts the url of the specified format through an IHttpHandlerFactory, then gets the fully qualified name of the type from it to generate the type object, and then obtains the characteristics of the tag method through reflection to generate a custom object that implements the IHttpHandler interface; in its ProcessRequest method, it gets the method name from http headers, maps parameters through reflection and executes the function.
Ajaxpro has the following advantages:
1. The configuration is simple.
two。 Can be used with other components.
3. Encapsulate the foreground script, we don't have to package or use other script libraries ourselves.
4. For return value processing, we can return simple types or complex types are automatically serialized.
The disadvantages are:
1. There will be 4 more requests on the page. Although the 304 cache is utilized, the request needs to be sent to the server.
2. Ajax cannot use Get request. Because of the custom url format, it is impossible to use Get requests with this format. We know that Get requests can be cached by browsers. One of Yahoo's front-end optimization recommendations is multi-use get requests. In fact, you should put the namespace. The class name, the assembly is put into http header, and then a parameter of type type is provided for us to choose freely.
3. And bind. The goal is to generate foreground scripts for us, but not if we want to use the .html file + .aspx.cs (as is the case for some pages in the blog park); even our interface may be used for mobile use, this convenience becomes a limitation.
4. Reflex. This is inefficient, and it doesn't even cache MethodInfo like our previous page classes.
As you can see, this component is worth using if you don't care too much about efficiency. Here is just a core introduction, there are many other functions, this is the source code of ajaxpro components, interested friends can study.
This is the answer to the question about writing the lightweight ajax component 02Mel-the example analysis of AjaxPro. I hope the above content can be of some help to you. If you still have a lot of doubts to solve, you can follow the industry information channel for more related knowledge.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.