国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Asp.net下的對象成員數(shù)據(jù)綁定器實現(xiàn)

2019-11-18 16:40:58
字體:
供稿:網(wǎng)友

       用過MonoRail的朋友應(yīng)該知道它提供的對象成員數(shù)據(jù)綁定功能非常方便,通過標(biāo)記參數(shù)屬性或方法就可以自動把提交回來的數(shù)據(jù)和對象成員進行綁定;有了這些方便的功能的確可以節(jié)省大量的set代碼。不過這些功能只是MonoRail提供,于是實現(xiàn)類似的功能方便自己開發(fā)。

實現(xiàn)目標(biāo):
       可以靈活方便地實現(xiàn)數(shù)據(jù)綁定。

       OrderSearch search = FormContext.BindObject<OrderSearch>();

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

制定規(guī)則和約束
       首先確定WEB提交的數(shù)據(jù)和成員屬性的映射關(guān)系,可以通過名稱約定的方式:

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

       xxxx.LastName、xxxx_LastName或xxxxLastName等。在綁過程可以指定前綴進行對象成員的綁定;不過在webForm控件的Name是asp.net生成的,在關(guān)系分析上就相對復(fù)雜些。

       類型轉(zhuǎn)換接口的定義
因為轉(zhuǎn)換的情況是很難確定;除了。NET的基礎(chǔ)類型外實際應(yīng)用中還會存在其他轉(zhuǎn)換方式,如:HttpPostedFile到byte[],序列化String到Object等。因此制定轉(zhuǎn)換接口就可以方便實現(xiàn)可擴展和可配置。

    public interface IStringConverter

    {

        object ConvertTo(string value, out bool succeeded);

       

    }

由于Web提供的數(shù)據(jù)大部份是以string的方式提供,因此定義一個基于string轉(zhuǎn)換描述。基于接口的實也很簡單:

    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工廠的實現(xiàn)
       由于轉(zhuǎn)換情況的不確定性,因此通過工廠的方式來達到代碼對外的封閉性和良好的擴展性。可以通過目標(biāo)類型來獲取相關(guān)轉(zhuǎn)換實例,在.NET中IDictionary就能夠達到應(yīng)用的要求。

        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();

           

        }

        //從配置文件加載轉(zhuǎn)換器映射,如果配置存在相同類型轉(zhuǎn)器就取代原有轉(zhuǎn)換器

        static void LoadConfig()

        {

            //Load Config

            // <converter type="System.Int32",value="Hfsoft.Binder.ToByte"

        }

為了方便使用可以在工廠中硬編碼配置內(nèi)部基礎(chǔ)類型;因為轉(zhuǎn)換情況的不確定,所以允許通過配置文件的方式引入不同情況的類型轉(zhuǎn)換器。

可以擴展性的Custom Attribute
       雖然工廠可以達到轉(zhuǎn)換接口的可配置性,但實際上很難達到應(yīng)用要求;在某些情況下類型轉(zhuǎn)換器只是在某些對象成員中有效(雖然配置文件也可以達到期要求,但在配置文件中定義這么小的粒度并不是好的選擇);通過Attribute給相關(guān)PRoperty指定類型轉(zhuǎn)換器非常適合。

   /// <summary>

    /// 用于特殊情況下描述對象具體成員的轉(zhuǎn)換器

    /// </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;

            }

        }

以上定義可以上傳文件流轉(zhuǎn)成byte[]到FileStream屬性中。

功能集成實現(xiàn)
       現(xiàn)在就把所有東西集成起來,滿足目的的要求。

        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提交的數(shù)據(jù)幾乎可以通過HttpRequest.Params得到,只需要根據(jù)屬性名稱和相關(guān)前綴進行匹配查找就可以了。這里實現(xiàn)的匹配方式并不理想,其實可以在相關(guān)page第一次請求就可以分析到關(guān)系存在IDictionary中,后期直接使用就可以了。

 

       以上功能是在編寫一個MVC組件的數(shù)據(jù)綁定功能,其實完全可以移植傳統(tǒng)的WebForm下工作;有更好想法的朋友請多提交意見。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 滦平县| 肥乡县| 两当县| 慈利县| 阳信县| 台安县| 原阳县| 疏附县| 米林县| 凤台县| 高陵县| 东港市| 丰县| 凤阳县| 保德县| 松原市| 台中县| 大悟县| 丽江市| 弋阳县| 固安县| 桦南县| 应用必备| 申扎县| 丹阳市| 庆阳市| 通化市| 衡山县| 西乡县| 绥棱县| 双辽市| 运城市| 抚顺市| 定远县| 库尔勒市| 南昌市| 高台县| 繁昌县| 萨嘎县| 神池县| 沁源县|