typejavascripthandler.cs
来自「AJAX开发工具包」· CS 代码 · 共 245 行
CS
245 行
/*
* MS 06-04-05 fixed sessionID on ASP.NET 2.0
* fixed Object.prototype.extend problem when running with third-party libs
* MS 06-04-12 added useAssemblyQualifiedName
*
*/
using System;
using System.Reflection;
using System.Web;
using System.Web.SessionState;
using System.Web.Caching;
using System.IO;
namespace AjaxPro
{
/// <summary>
/// Represents an IHttpHandler for the client-side JavaScript wrapper.
/// </summary>
internal class TypeJavaScriptHandler : IHttpHandler, IReadOnlySessionState // need IReadOnlySessionState to check if using cookieless session ID
{
// TODO: The session ID has to be used in the cache of core and types.js
private Type type;
internal TypeJavaScriptHandler(Type type)
{
this.type = type;
}
#region IHttpHandler Members
public void ProcessRequest(HttpContext context)
{
// The request was not a request to invoke a server-side method.
// Now, we will render the Javascript that will be used on the
// client to run as a proxy or wrapper for the methods marked
// with the AjaxMethodAttribute.
if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "Render class proxy Javascript");
System.Reflection.MethodInfo[] mi = type.GetMethods();
// Check wether the javascript is already rendered and cached in the
// current context.
string etag = context.Request.Headers["If-None-Match"];
string modSince = context.Request.Headers["If-Modified-Since"];
string path = type.FullName + "," + type.Assembly.FullName.Split(',')[0];
if (Utility.Settings.UseAssemblyQualifiedName) path = type.AssemblyQualifiedName;
if(Utility.Settings != null && Utility.Settings.UrlNamespaceMappings.ContainsValue(path))
{
foreach(string key in Utility.Settings.UrlNamespaceMappings.Keys)
{
if(Utility.Settings.UrlNamespaceMappings[key].ToString() == path)
{
path = key;
break;
}
}
}
if(context.Cache[path] != null)
{
CacheInfo ci = (CacheInfo)context.Cache[path];
if(etag != null)
{
if(etag == ci.ETag) // TODO: null check
{
context.Response.StatusCode = 304;
return;
}
}
if(modSince != null)
{
try
{
DateTime modSinced = Convert.ToDateTime(modSince.ToString()).ToUniversalTime();
if(DateTime.Compare(modSinced, ci.LastModified.ToUniversalTime()) >= 0)
{
context.Response.StatusCode = 304;
return;
}
}
catch(Exception)
{
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.");
}
}
}
etag = type.AssemblyQualifiedName; // + "_" + type.Assembly. DateTime.Now.ToString(System.Globalization.DateTimeFormatInfo.CurrentInfo.SortableDateTimePattern);
etag = MD5Helper.GetHash(System.Text.Encoding.Default.GetBytes(etag));
DateTime now = DateTime.Now;
DateTime lastMod = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); // .ToUniversalTime();
context.Response.AddHeader("Content-Type", "application/x-javascript");
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
context.Response.Cache.SetETag(etag);
context.Response.Cache.SetLastModified(lastMod);
// Ok, we do not have the javascript rendered, yet.
// Build the javascript source and save it to the current
// Application context.
System.Text.StringBuilder sb = new System.Text.StringBuilder();
AjaxNamespaceAttribute[] cma = (AjaxNamespaceAttribute[])type.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
string clientNS = type.FullName;
if(cma.Length > 0 && cma[0].ClientNamespace != null)
{
if(cma[0].ClientNamespace.IndexOf(".") > 0)
sb.Append("addNamespace(\"" + cma[0].ClientNamespace + "\");\r\n");
clientNS = cma[0].ClientNamespace;
}
else
{
sb.Append("addNamespace(\"" + (type.FullName.IndexOf(".") > 0 ? type.FullName.Substring(0, type.FullName.LastIndexOf(".")) : type.FullName) + "\");\r\n");
}
sb.Append(clientNS);
sb.Append("_class = Class.create();\r\n");
sb.Append("Object.extend(");
sb.Append(clientNS);
sb.Append("_class.prototype, Object.extend(new AjaxPro.AjaxClass(), {\r\n");
System.Reflection.MethodInfo method;
for(int y=0; y<mi.Length; y++)
{
method = mi[y];
if(!method.IsPublic)
continue;
AjaxNamespaceAttribute[] cmam = (AjaxNamespaceAttribute[])method.GetCustomAttributes(typeof(AjaxNamespaceAttribute), true);
AjaxMethodAttribute[] ma = (AjaxMethodAttribute[])method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
if(ma.Length == 0)
continue;
System.Reflection.ParameterInfo[] pi = method.GetParameters();
// Render the function header
sb.Append("\t");
if(cmam.Length == 0)
sb.Append(method.Name);
else
sb.Append(cmam[0].ClientNamespace);
sb.Append(": function(");
// Render all parameters
for(int i=0; i<pi.Length; i++)
{
sb.Append(pi[i].Name);
if(i<pi.Length -1)
sb.Append(", ");
}
sb.Append(") {\r\n");
// Create the XMLHttpRequest object
sb.Append("\t\treturn this.invoke(\"" + method.Name + "\", {"); // must be the original method name
for(int i=0; i<pi.Length; i++)
{
sb.Append("\"");
sb.Append(pi[i].Name);
sb.Append("\":");
sb.Append(pi[i].Name);
if(i<pi.Length -1)
sb.Append(", ");
}
sb.Append("}, this.");
if(cmam.Length == 0)
sb.Append(method.Name);
else
sb.Append(cmam[0].ClientNamespace);
sb.Append(".getArguments().slice(");
sb.Append(pi.Length.ToString());
sb.Append("));\r\n\t},\r\n");
}
string url = context.Request.ApplicationPath + (context.Request.ApplicationPath.EndsWith("/") ? "" : "/") + Utility.HandlerPath + "/" + AjaxPro.Utility.GetSessionUri() + path + Utility.HandlerExtension;
sb.Append("\tinitialize: function() {\r\n\t\tthis.url = '" + url + "';\r\n\t}\r\n");
sb.Append("}));\r\n");
sb.Append(clientNS);
sb.Append(" = new ");
sb.Append(clientNS);
sb.Append("_class();\r\n");
// save the javascript in current Application context to
// speed up the next requests.
// TODO: was k鰊nen wir hier machen??
// System.Web.Caching.CacheDependency fileDepend = new System.Web.Caching.CacheDependency(type.Assembly.Location);
context.Cache.Add(path, new CacheInfo(etag, lastMod), null,
System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.Normal, null);
context.Response.Write(sb.ToString());
context.Response.Write("\r\n");
if(context.Trace.IsEnabled) context.Trace.Write(Constant.AjaxID, "End ProcessRequest");
}
public bool IsReusable
{
get
{
// TODO: Add CoreJavaScriptHandler.IsReusable getter implementation
return false;
}
}
#endregion
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?