TypeJavaScriptHandler.cs
上传用户:szgaoree
上传日期:2009-01-05
资源大小:74k
文件大小:7k
源码类别:

Ajax

开发平台:

C#

  1. /*
  2.  * MS 06-04-05 fixed sessionID on ASP.NET 2.0
  3.  * fixed Object.prototype.extend problem when running with third-party libs
  4.  * MS 06-04-12 added useAssemblyQualifiedName
  5.  * 
  6.  */
  7. using System;
  8. using System.Reflection;
  9. using System.Web;
  10. using System.Web.SessionState;
  11. using System.Web.Caching;
  12. using System.IO;
  13. namespace AjaxPro
  14. {
  15. /// <summary>
  16. /// Represents an IHttpHandler for the client-side JavaScript wrapper.
  17. /// </summary>
  18. internal class TypeJavaScriptHandler : IHttpHandler, IReadOnlySessionState // need IReadOnlySessionState to check if using cookieless session ID
  19. {
  20. // TODO: The session ID has to be used in the cache of core and types.js
  21. private Type type;
  22. internal TypeJavaScriptHandler(Type type)
  23. {
  24. this.type = type;
  25. }
  26. #region IHttpHandler Members
  27. public void ProcessRequest(HttpContext context)
  28. {
  29. // The request was not a request to invoke a server-side method.
  30. // Now, we will render the Javascript that will be used on the
  31. // client to run as a proxy or wrapper for the methods marked
  32. // with the AjaxMethodAttribute.
  33. if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "Render class proxy Javascript");
  34. System.Reflection.MethodInfo[] mi = type.GetMethods();
  35. // Check wether the javascript is already rendered and cached in the
  36. // current context.
  37. string etag = context.Request.Headers["If-None-Match"];
  38. string modSince = context.Request.Headers["If-Modified-Since"];
  39. string path = type.FullName + "," + type.Assembly.FullName.Split(',')[0];
  40. if (Utility.Settings.UseAssemblyQualifiedName) path = type.AssemblyQualifiedName;
  41. if(Utility.Settings != null && Utility.Settings.UrlNamespaceMappings.ContainsValue(path))
  42. {
  43. foreach(string key in Utility.Settings.UrlNamespaceMappings.Keys)
  44. {
  45. if(Utility.Settings.UrlNamespaceMappings[key].ToString() == path)
  46. {
  47. path = key;
  48. break;
  49. }
  50. }
  51. }
  52. if(context.Cache[path] != null)
  53. {
  54. CacheInfo ci = (CacheInfo)context.Cache[path];
  55. if(etag != null)
  56. {
  57. if(etag == ci.ETag) // TODO: null check
  58. {
  59. context.Response.StatusCode = 304;
  60. return;
  61. }
  62. }
  63. if(modSince != null)
  64. {
  65. try
  66. {
  67. DateTime modSinced = Convert.ToDateTime(modSince.ToString()).ToUniversalTime();
  68. if(DateTime.Compare(modSinced, ci.LastModified.ToUniversalTime()) >= 0)
  69. {
  70. context.Response.StatusCode = 304;
  71. return;
  72. }
  73. }
  74. catch(Exception)
  75. {
  76. if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "The header value for If-Modified-Since = " + modSince + " could not be converted to a System.DateTime.");
  77. }
  78. }
  79. }
  80. etag = type.AssemblyQualifiedName; // + "_" + type.Assembly. DateTime.Now.ToString(System.Globalization.DateTimeFormatInfo.CurrentInfo.SortableDateTimePattern);
  81. etag = MD5Helper.GetHash(System.Text.Encoding.Default.GetBytes(etag));
  82. DateTime now = DateTime.Now;
  83. DateTime lastMod = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); // .ToUniversalTime();
  84. context.Response.AddHeader("Content-Type", "application/x-javascript");
  85. context.Response.ContentEncoding = System.Text.Encoding.UTF8;
  86. context.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
  87. context.Response.Cache.SetETag(etag);
  88. context.Response.Cache.SetLastModified(lastMod);
  89. // Ok, we do not have the javascript rendered, yet.
  90. // Build the javascript source and save it to the current
  91. // Application context.
  92. System.Text.StringBuilder sb = new System.Text.StringBuilder();
  93. AjaxNamespaceAttribute[] cma = (AjaxNamespaceAttribute[])type.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
  94. string clientNS = type.FullName;
  95. if(cma.Length > 0 && cma[0].ClientNamespace != null)
  96. {
  97. if(cma[0].ClientNamespace.IndexOf(".") > 0)
  98. sb.Append("addNamespace("" + cma[0].ClientNamespace + "");rn");
  99. clientNS = cma[0].ClientNamespace;
  100. }
  101. else
  102. {
  103. sb.Append("addNamespace("" + (type.FullName.IndexOf(".") > 0 ? type.FullName.Substring(0, type.FullName.LastIndexOf(".")) : type.FullName) + "");rn");
  104. }
  105. sb.Append(clientNS);
  106. sb.Append("_class = Class.create();rn");
  107. sb.Append("Object.extend(");
  108. sb.Append(clientNS);
  109. sb.Append("_class.prototype, Object.extend(new AjaxPro.AjaxClass(), {rn");
  110. System.Reflection.MethodInfo method;
  111. for(int y=0; y<mi.Length; y++)
  112. {
  113. method = mi[y];
  114. if(!method.IsPublic)
  115. continue;
  116. AjaxNamespaceAttribute[] cmam = (AjaxNamespaceAttribute[])method.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
  117. AjaxMethodAttribute[] ma = (AjaxMethodAttribute[])method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
  118. if(ma.Length == 0)
  119. continue;
  120. System.Reflection.ParameterInfo[] pi = method.GetParameters();
  121. // Render the function header
  122. sb.Append("t");
  123. if(cmam.Length == 0)
  124. sb.Append(method.Name);
  125. else
  126. sb.Append(cmam[0].ClientNamespace);
  127. sb.Append(": function(");
  128. // Render all parameters
  129. for(int i=0; i<pi.Length; i++)
  130. {
  131. sb.Append(pi[i].Name);
  132. if(i<pi.Length -1)
  133. sb.Append(", ");
  134. }
  135. sb.Append(") {rn");
  136. // Create the XMLHttpRequest object
  137. sb.Append("ttreturn this.invoke("" + method.Name + "", {"); // must be the original method name
  138. for(int i=0; i<pi.Length; i++)
  139. {
  140. sb.Append(""");
  141. sb.Append(pi[i].Name);
  142. sb.Append("":");
  143. sb.Append(pi[i].Name);
  144. if(i<pi.Length -1)
  145. sb.Append(", ");
  146. }
  147. sb.Append("}, this.");
  148. if(cmam.Length == 0)
  149. sb.Append(method.Name);
  150. else
  151. sb.Append(cmam[0].ClientNamespace);
  152. sb.Append(".getArguments().slice(");
  153. sb.Append(pi.Length.ToString());
  154. sb.Append("));rnt},rn");
  155. }
  156. string url = context.Request.ApplicationPath + (context.Request.ApplicationPath.EndsWith("/") ? "" : "/") + Utility.HandlerPath + "/" + AjaxPro.Utility.GetSessionUri() + path + Utility.HandlerExtension;
  157. sb.Append("tinitialize: function() {rnttthis.url = '" + url + "';rnt}rn");
  158. sb.Append("}));rn");
  159. sb.Append(clientNS);
  160. sb.Append(" = new ");
  161. sb.Append(clientNS);
  162. sb.Append("_class();rn");
  163. // save the javascript in current Application context to
  164. // speed up the next requests.
  165. // TODO: was k鰊nen wir hier machen??
  166. // System.Web.Caching.CacheDependency fileDepend = new System.Web.Caching.CacheDependency(type.Assembly.Location);
  167. context.Cache.Add(path, new CacheInfo(etag, lastMod), null, 
  168. System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration,
  169. System.Web.Caching.CacheItemPriority.Normal, null);
  170. context.Response.Write(sb.ToString());
  171. context.Response.Write("rn");
  172. if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "End ProcessRequest");
  173. }
  174. public bool IsReusable
  175. {
  176. get
  177. {
  178. // TODO:  Add CoreJavaScriptHandler.IsReusable getter implementation
  179. return false;
  180. }
  181. }
  182. #endregion
  183. }
  184. }