zoukankan      html  css  js  c++  java
  • Ajax的一个封装[原创]

    刚刚差点把封装打成装疯......好吧,开始了,ASP.NET中ajax请求的目标大多是webservice和ashx,以及少量指向自己页面的,webservice客户端通用,但是性能差点,ashx挺完美的,性能最快,但这货没写一个业务,就得创建一个文件,这种我也是非常不爽。

    ashx的的实现是基于IHttpHandler接口的,这个接口还是挺简单的。

    AJAX请求数量会越来越多,我们用一个简单的工厂模式来分流。

    public class AjaxHandlerFactory : IHttpHandlerFactory
        {
            /// <summary>
            /// 缓存,用于缓存请求的Ajax实例
            /// </summary>
            private System.Web.Caching.Cache _cache = HttpContext.Current.Cache;
            /// <summary>
            /// 用参数类名(ClassName)返回ajax业务类
            /// </summary>
            /// <param name="strUrlPath"></param>
            /// <returns></returns>
            private string GetClassName(string strClass)
            {
                return string.Format("EMS.WebUtility.HttpHandler.Ajax.{0}, EMS.WebUtility", strClass);
            }
            #region IHttpHandlerFactory 成员
    
            public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
            {
                string strClass = context.Request.Params["ClassName"];
                if (string.IsNullOrEmpty(strClass)) return null;
                string strClassName = GetClassName(strClass);
                //优先从缓存中获取实例
                object handle = _cache.Get(strClassName);
                if (handle != null)
                {
                    return (IHttpHandler)handle;
                }
    
                Type t = Type.GetType(strClassName, false, true);
                if (t != null)
                {
                    if (t.GetInterface("IHttpHandler", true) != null)
                    {
                        return (IHttpHandler)Activator.CreateInstance(t);
                    }
                }
                return null;
            }
    
            public void ReleaseHandler(IHttpHandler handler)
            {
                //如果handle不为null,且设置了IsReusable为true,则缓存handle
                if (handler != null && handler.IsReusable)
                {
                    string className = handler.GetType().FullName.ToUpper();
                    _cache.Insert(className, handler, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 10, 0));
                }
            }
    
            #endregion
        }
    

    这里通过参数ClassName来确定具体的业务类,通过反射实例化,同时这个地方做了缓存,

      

    在写一个抽象的基类:

    public abstract class AjaxHandler : IHttpHandler
        {
            /// <summary>
            /// You will need to configure this handler in the web.config file of your 
            /// web and register it with IIS before being able to use it. For more information
            /// see the following link: http://go.microsoft.com/?linkid=8101007
            /// </summary>
            #region IHttpHandler Members
    
            public bool IsReusable
            {
                // Return false in case your Managed Handler cannot be reused for another request.
                // Usually this would be false in case you have some state information preserved per request.
                get { return true; }
            }
    
            public virtual string ContengType
            {
                get { return "text/html"; }
            }
    
            /// <summary>
            /// 输出数据,请继承
            /// </summary>
            /// <returns></returns>
            public abstract string GetBusinessData();
    
            public void ProcessRequest(HttpContext context)
            {
                context.Response.ContentEncoding = Encoding.UTF8;
                context.Response.ContentType = ContengType;
    
                AjaxMappingAttribute.Bind(this, context.Request.Params);
    
                context.Response.Output.Write(GetBusinessData());
                context.Response.End();
            }
    
            #endregion
        }
    

      GetBusinessData()是由具体业务类实现的,业务类需要继承上面这个类:

    public class GetPctCode : AjaxHandler
        {
            [AjaxMapping("name", true)]
            public string StreetName { get; set; }
    
            [AjaxMapping("Number", true)]
            public string StreetNum { get; set; }
    
            [AjaxMapping("Quandrant", true)]
            public string Quandrant { get; set; }
    
            [AjaxMapping("StType", false)]
            public string StType { get; set; }
    
            public override string GetBusinessData()
            {
                string SubDivistion = BLLClasses.EMS_Street.GetStreetPCTCodeByStreetNameAndNum(StreetName, StreetNum, "", Quandrant, StType);
                return SubDivistion;
            }
        }
    

      这里还用到了AjaxMapping特性,他的功能是映射参数的值到业务类的属性中:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
        public class AjaxMappingAttribute : System.Attribute 
        {
            /// <summary>
            /// 参数名称
            /// </summary>
            public string ParamName { get; set; }
            /// <summary>
            /// 是否必须
            /// </summary>
            public bool IsRequired { get; set; }
            //构造函数
            public AjaxMappingAttribute() : this(null, false) { }
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="paramName"></param>
            /// <param name="isRequired"></param>
            public AjaxMappingAttribute(string paramName, bool isRequired)
            {
                this.ParamName = paramName;
                this.IsRequired = isRequired;
            }
            /// <summary>
            /// 绑定参数
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="param"></param>
            public static void Bind(object obj, NameValueCollection param)
            {
                Mappinger.Mapping<AjaxMappingAttribute>(obj, (paramName, mt) =>
                {
                    return param[paramName];
                });
            }
        }
    
        /// <summary>
        /// 属性映射,接收的URL参数映射到相关类上标识为MappingAttribute的属性上
        /// </summary>
        public class Mappinger
        {
            public static void Mapping<T>(object obj, Func<string, T, string> getParamValue) where T : AjaxMappingAttribute
            {
                Type t = obj.GetType();
                foreach (PropertyInfo pi in t.GetProperties())
                {
                    object[] customerAttributes = pi.GetCustomAttributes(typeof(T), false);
                    if (customerAttributes.Length == 1)
                    {
                        MethodInfo setMethod = pi.GetSetMethod();
                        if (setMethod != null)
                        {
                            T mapping = customerAttributes[0] as T;
                            //参数名称,如果没有指定参数名称,则默认为属性名称
                            string paramName = string.IsNullOrEmpty(mapping.ParamName) ? pi.Name : mapping.ParamName;
    
                            string paramValue = getParamValue(paramName, mapping);
                            if (paramValue == null)
                            {
                                if (mapping.IsRequired)
                                {
                                    throw new ArgumentNullException(string.Format("未提供参数{0}的值", paramName));
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            setMethod.Invoke(obj, new object[] { paramValue });
                        }
                        else
                        {
                            throw new Exception(string.Format("未定义数据{0}的set构造器,无法进行赋值。", pi.Name));
                        }
                    }
                }
            }
        }
    

      

    以上内容大多抄袭了yangrong.g这篇文章

    yangrong.g的请求是用aspx去映射,我打算另一种办法

    用ASP.NET Ajax库就知道会有个ScriptManager,客户端会渲染出一个Resources.axd?XXXXXX的请求,这个axd是在项目中不存在的,就是个URL路由,其实ashx也是这样的一个东西,那我在这里入手,把请求都统一到一个AjaxHandler.axd里:

    <add verb="*" path="AjaxHandler.axd" type="EMS.WebUtility.HttpHandler.AjaxHandlerFactory, EMS.WebUtility"/>

    客户端的请求只要:

    $.post("/AjaxHandler.axd?ClassName=GetPctCode",....

     

  • 相关阅读:
    ExtJS 4.0 改善Ext.grid.plugin.RowEditing (重构,v1.4版本,20110911)
    GeoServer源码解析和扩展 (四)文件系统
    Ext蒙板效果
    Ext Grid表格的自动宽度及高度的实现
    Extjs4用RowEditing对数据进行增加,修改
    ExtJs4.0 Grid分頁詳解
    canvas的处理图片功能
    cookie的设置和读取
    html5的canvas知识
    初学jquery mobile
  • 原文地址:https://www.cnblogs.com/405464904/p/2473822.html
Copyright © 2011-2022 走看看