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

首頁 > 編程 > .NET > 正文

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

2024-07-10 13:08:39
字體:
供稿:網(wǎng)友

    用過monorail的朋友應(yīng)該知道它提供的對象成員數(shù)據(jù)綁定功能非常方便,通過標(biāo)記參數(shù)屬性或方法就可以自動把提交回來的數(shù)據(jù)和對象成員進(jìn)行綁定;有了這些方便的功能的確可以節(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等。在綁過程可以指定前綴進(jìn)行對象成員的綁定;不過在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)可擴(kuò)展和可配置。

    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)換情況的不確定性,因此通過工廠的方式來達(dá)到代碼對外的封閉性和良好的擴(kuò)展性。可以通過目標(biāo)類型來獲取相關(guān)轉(zhuǎn)換實例,在.net中idictionary就能夠達(dá)到應(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)換器。

可以擴(kuò)展性的custom attribute

  雖然工廠可以達(dá)到轉(zhuǎn)換接口的可配置性,但實際上很難達(dá)到應(yīng)用要求;在某些情況下類型轉(zhuǎn)換器只是在某些對象成員中有效(雖然配置文件也可以達(dá)到期要求,但在配置文件中定義這么小的粒度并不是好的選擇);通過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)前綴進(jìn)行匹配查找就可以了。這里實現(xiàn)的匹配方式并不理想,其實可以在相關(guān)page第一次請求就可以分析到關(guān)系存在idictionary中,后期直接使用就可以了。

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

國內(nèi)最大的酷站演示中心!
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 招远市| 岳阳市| 如东县| 共和县| 新巴尔虎右旗| 射阳县| 株洲市| 塔河县| 永州市| 甘孜县| 昭通市| 石家庄市| 集贤县| 鄂托克前旗| 蒙城县| 新乡市| 新河县| 措勤县| 罗山县| 青龙| 乾安县| 柏乡县| 余江县| 邹平县| 金沙县| 固镇县| 托克逊县| 长春市| 关岭| 丹东市| 张家界市| 蒙城县| 喀什市| 湟中县| 大关县| 沧源| 辽宁省| 渑池县| 鱼台县| 商洛市| 南涧|