Asp.net下的对象成员数据绑定器实现

asp.net|对象|数据

    用过MonoRail的朋友应该知道它提供的对象成员数据绑定功能非常方便,通过标记参数属性或方法就可以自动把提交回来的数据和对象成员进行绑定;有了这些方便的功能的确可以节省大量的set代码。不过这些功能只是MonoRail提供,于是实现类似的功能方便自己开发。

  实现目标:可以灵活方便地实现数据绑定。

  OrderSearch search = FormContext.BindObject<OrderSearch>();
  Orders order = FormContext.BindObject<Orders>("order");

  制定规则和约束

  首先确定WEB提交的数据和成员属性的映射关系,可以通过名称约定的方式:

  <input id="Text1" name="companyname" type="text" />

  xxxx.LastName、xxxx_LastName或xxxxLastName等。在绑过程可以指定前缀进行对象成员的绑定;不过在webForm控件的Name是asp.net生成的,在关系分析上就相对复杂些。

  类型转换接口的定义

  因为转换的情况是很难确定;除了。NET的基础类型外实际应用中还会存在其他转换方式,如:HttpPostedFile到byte[],序列化String到Object等。因此制定转换接口就可以方便实现可扩展和可配置。

    public interface IStringConverter
    {
        object ConvertTo(string value, out bool succeeded);
    }

  由于Web提供的数据大部份是以string的方式提供,因此定义一个基于string转换描述。基于接口的实也很简单:

    public class ToSbyte    :IStringConverter
    {
        #region IStringConverter 成员
        object IStringConverter.ConvertTo(string value, out bool succeeded)
        {
            sbyte nvalue;
            succeeded = sbyte.TryParse(value, out nvalue);
            return nvalue;
        }
        #endregion
    }

  IStringConverter工厂的实现

  由于转换情况的不确定性,因此通过工厂的方式来达到代码对外的封闭性和良好的扩展性。可以通过目标类型来获取相关转换实例,在.NET中IDictionary就能够达到应用的要求。

        static IDictionary<Type, IStringConverter> mConverters;
        public static IDictionary<Type, IStringConverter> Converters
        {
            get
            {
                if (mConverters == null)
                {
                    lock (typeof(ConverterFactory))
                    {
                        OnInit();
                    }
                }
                return mConverters;
            }
        }
        static void OnInit()
        {
            if (mConverters != null)
                return;
            mConverters = new Dictionary<Type, IStringConverter>();
            mConverters.Add(typeof(byte), new ToByte());
            LoadConfig();
        }
        //从配置文件加载转换器映射,如果配置存在相同类型转器就取代原有转换器
        static void LoadConfig()
        {
            //Load Config
            // <converter type="System.Int32",value="HFSoft.Binder.ToByte"
        }

为了方便使用可以在工厂中硬编码配置内部基础类型;因为转换情况的不确定,所以允许通过配置文件的方式引入不同情况的类型转换器。

可以扩展性的Custom Attribute

  虽然工厂可以达到转换接口的可配置性,但实际上很难达到应用要求;在某些情况下类型转换器只是在某些对象成员中有效(虽然配置文件也可以达到期要求,但在配置文件中定义这么小的粒度并不是好的选择);通过Attribute给相关Property指定类型转换器非常适合。

   /// <summary>
    /// 用于特殊情况下描述对象具体成员的转换器
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class ConverterAttribute : Attribute, IStringConverter
    {
        public ConverterAttribute(Type convertertype)
        {
            mConverterType = convertertype;
        }
        public ConverterAttribute(Type convertertype, string defvalue)
        {
            mConverterType = convertertype;
            mDefaultValue = defvalue;
        }
        private Type mConverterType;
        public Type ConverterType
        {
            get
            {
                return mConverterType;
            }
        }

        private String mDefaultValue;
        public String DefaultValue
        {
            get
            {
                return mDefaultValue;
            }
            set
            {
                mDefaultValue = value;
            }
        }

        protected IStringConverter CreateInstance()
        {
            if (mConverters.ContainsKey(ConverterType))
                return mConverters[ConverterType];
            lock (typeof(ConverterAttribute))
            {
                if (!mConverters.ContainsKey(ConverterType))
                {
                    mConverters.Add(ConverterType, (IStringConverter)Activator.CreateInstance(ConverterType));
                }
                return mConverters[ConverterType];
            }
        }
        static IDictionary<Type, IStringConverter> mConverters = new Dictionary<Type, IStringConverter>();
        #region IStringConverter 成员
        public object ConvertTo(string value, out bool succeeded)
        {
            string newvalue = value != null ? value : DefaultValue;
            return CreateInstance().ConvertTo(newvalue, out succeeded);
        }
        #endregion
    }

通过ConverterAttribute可以方便制定粒度更小的配置

private byte[] mFileStream;
   [Converter(typeof(FileStreamConverter),"IconPhoto")]
        public byte[] FileStream
        {
            get
            {
                return mFileStream;
            }
            set
            {
                mFileStream = value;
            }
        }

以上定义可以上传文件流转成byte[]到FileStream属性中。

功能集成实现
       现在就把所有东西集成起来,满足目的的要求。

        public object Bind(System.Collections.Specialized.NameValueCollection values, string prefix)
        {
           object newobj = Activator.CreateInstance(ObjectType);

            if (prefix == null)

                prefix = "";

            object value;

            foreach (PropertyInfo item in Properties)
           {
                value = values[prefix + "." + item.Name];
                if(value == null)
                    value = values[prefix + "_" + item.Name];
                if(value == null)
                    value = values[prefix + item.Name];
                BindProperty(newobj, item, (string)value);
            }
            return newobj;
        }

       private void BindProperty(object obj, PropertyInfo property, string value)
        {
            IStringConverter stringconver;
            object nvalue;
            bool confirm = false;
            Object[] cas = property.GetCustomAttributes(typeof(ConverterAttribute), true);
            if (cas.Length > 0)
            {
               nvalue = ((ConverterAttribute)cas[0]).ConvertTo(value, out confirm);
                if (confirm)
                    mPropertiesHandle[property].SetValue(obj, nvalue);
            }
            else
            {
                if (ConverterFactory.Converters.ContainsKey(property.PropertyType))
                {
                    stringconver = ConverterFactory.Converters[property.PropertyType];
                    nvalue = stringconver.ConvertTo(value, out confirm);
                    if (confirm)
                        mPropertiesHandle[property].SetValue(obj, nvalue);
                }
           }
        }

  因为Web提交的数据几乎可以通过HttpRequest.Params得到,只需要根据属性名称和相关前缀进行匹配查找就可以了。这里实现的匹配方式并不理想,其实可以在相关page第一次请求就可以分析到关系存在IDictionary中,后期直接使用就可以了。

  以上功能是在编写一个MVC组件的数据绑定功能,其实完全可以移植传统的WebForm下工作;有更好想法的朋友请多提交意见。

时间: 2024-10-30 22:29:51

Asp.net下的对象成员数据绑定器实现的相关文章

在Web界面下如何生成像资源管理器一样的树形目录(版本2.0) eeff(原作) [精]

web 在Web界面下如何生成像资源管理器一样的树形目录(版本2.0)    eeff(原作)    关键字     数形目录 XML ASP Web Javascript    树形目录显示程序问题描述: 在我们项目中常常会出现自关联的数据表,如果我们从整体看去,整个表就呈现为一个树形数据结构(对于复杂的情况,它可能变成一个图).当我们对这个表进行显示,编辑时,如果不采用好的表现形式,会显得很笨拙,为此,我们开发这样的树形结构的程序.在上一版本中,我们使用的是递归算法来实现,在我们对这个算法评

ASP.NET下MVC设计模式的实现

asp.net|设计 ASP.NET是微软最新推出的新型体系结构.NET框架的一部分,它为构造新一代动态网站和基于网络的分布式应用提供了强有力的支持.与以前的 Web 开发模型相比,ASP.NET 提供了许多重要的优点例如: 简易性:安全性:可管理性等.而且与基于过程的ASP页面技术相比,面向对象技术在ASP.NET中得到了完全实现.用传统ASP技术建立的Web应用实例中,在页面中同时实现显示,业务逻辑和流程控制,这从工程化的角度考虑,它有许多不足之处.用户界面承担着向用户显示问题模型和与用户进

综述ASP.NET下的AJAX模式

本文内容: 一.导言 二.XMLHttp+WebForm模式 三.XMLHttp+HttpHandler模式 四.ASP.NET 2.0/3.5回调模式 五.AJAX框架模式 一.导言 在这篇文章中,将介绍在ASP.NET环节下的几种常用的AJAX模式.例如: XMLHttpRequest+WebForms,XMLHttpRequest+HttpHandlers,CallBacks,以及使用AJAX框架等,下面将以示 例结合的方式展开介绍这一系列常用模式.本文之后将提供示例代码下载. 二.XML

ASP.NET下使用WScript.Shell执行命令_实用技巧

ASP.NET提供了两种方法让我们使用COM组件:1.Server对象的CreatObject方法:2.将COM组件转化为.NET组件. ·Server对象的CreatObject方法 这个方法比较简单,直接使用就是.当然前提是服务器上已经注册了该组件,而WScript.Shell是系统自带的,我们不用担心.只是在编写代码时注意ASP.NET与ASP语法上的细微差别就可以了.直接给出代码如下: <!-- Titel: WScript.Shell .NET Version 1 Author: la

asp.net下web控件点评

asp.net下控件分二大类,分别在 System.Web.UI.WebControls System.Web.UI.HtmlControls 命名空间下,前者继承自WebControl,后者继承自HtmlControl,这二个类又都继承自System.Web.UI.Control额, windows平台,不论你从事什么开发,最终都需要有人调用loadlibrary.dll.那么asp.net控件,不论你使用什么控件,最终都要调用Render.其实做为前台开发,这些控件大部分不是那么好用. 1.

在ASP中利用“正则表达式” 对象实现UBB风格的论坛

ubb|对象|正则 上一次,我们谈到在ASP中如何利用"正则表达式"对象来实现各种数据的校验,文中描述了正则表达式对象的强大功能,接下来,我们来看看有关"正则表达式"对象的其他功能.当我们在网上冲浪的时候,尤其是浏览各类论坛的时候,经常会见到"UBB代码"这个词语.什么是UBB代码呢?UBB代码是HTML的一个变种http://www.alixixi.com/program/a/,是Ultimate Bulletin Board (国外一个BBS

认识ASP内置的对象

对象 认识ASP内置的对象 ASP内置Application,AspError,Request,Response,Session,ObjectContext,Server 等七个对象(Object), 而且每个对象有各自的属性(Property),方法(Method),集合(Collection)或事件(Event).现在我们就来介绍这几个名词的意义,好让我们更好地去理解ASP的内置对象: "对象"(Object)就像我们在日常生活中所看到的各种物体,例如计算机, 冰箱,汽车, 手机等

ASP中利用“正则表达式” 对象实现UBB代码

ubb|对象|正则 上一次,我们谈到在ASP中如何利用"正则表达式"对象来实现各种数据的校验,文中描述了正则表达式对象的强大功能,接下来,我们来看看有关"正则表达式"对象的其他功能.当我们在网上冲浪的时候,尤其是浏览各类论坛的时候,经常会见到"UBB代码"这个词语.什么是UBB代码呢?UBB代码是HTML的一个变种http://www.alixixi.com/program/a/,是Ultimate Bulletin Board (国外一个BBS

ASP环境下邮件列表功能的实现 (一)

邮件列表(Mailing List)是当前最受欢迎的网络服务之一.本文通过一个示例系统的建设,介绍在ASP环境下邮件列表功能的实现方法. ChinaByte网络学院的<Java Mail API及其应用>一文介绍了在Java中简单邮件列表服务功能的实现方法,本文介绍的是类似功能在ASP应用中的实现.我们将通过一个示例系统具体说明其实现过程. 一.系统概貌 整个应用系统可以分为两个部分,即面向最终用户的功能和面向管理任务的功能.面向最终用户的功能主要包括:提供输入界面让用户输入个人信息(用户名字