利用反射實現ASP.NET控制項和資料實體之間的雙向繫結,並且在用戶端自動驗證輸入的內容是否合法

來源:互聯網
上載者:User
首先請原諒我蹩腳的中文...玩電腦太多都不太會說話了,但願大家看的明白

ASP.NET的UI不像做Winform那麼容易,設個DataSource和DataField就什麼都搞定了.雖然提供了<%#%>這樣形式的綁定,但是這種綁定是單向的,只能從資料來源賦值給控制項,無法把控制項的內容寫回資料來源.所以,在儲存資料時得一條一條寫,還得處理null,類型轉換什麼的.例如
anObject.AnIntProperty =  Convert.ToInt32(aControl.Text == "" ? aControl.Text  : "0"); //用資料實體的話
或者
aDatarow["AnIntField"] =  Convert.ToInt32(aControl.Text == "" ? aControl.Text  : "0"); //用datarow的話
有時一張表單幾十個欄位,這樣寫準會瘋的 >_<

於是我利用反射做了一個東西,實現了讓控制項顯示資料實體(我慣用o-r mapping而不是DataSet/DataRow,當然DataRow也能用類似的方式去搞)的內容和把控制項的內容賦回給資料實體,然後,順便把資料合法性驗證也做進去了(反射效能損耗大,不幹多點東西心裡不平衡啊)

在我的BindingManager類中約定,凡是"_"結尾的控制項將會被處理,這些控制項會和實體類相對應的屬性自動關聯起來.通過設定PrefixLength的值指定從控制項名的第幾個字元開始匹配實體類屬性,例如我習慣用3個字元做控制項首碼,於是設PrefixLength為3,和Name屬性關聯的控制項名就形如txtName_.然後調用GetEntityValues(Page,theObject)和SetEntityValue(Page,theObject)來實現控制項和資料實體之間的綁定.

至於"順便"做的合法性驗證的功能,首先確保了控制項輸入的內容符合實體屬性的類型,這是自動完成的,例如一個int屬性對應的控制項不能填寫字母.如果有更多的要求,例如用Regex,不允許空值,或者在出錯時給使用者更詳細的提示,則給實體的屬性加上ValidateAttribute後就可以實現.

這是一個我寫的Demo的其中一部分:Person類,其中有各種不同類型的屬性.可以看到ValidateAttribute指定了Name不可空,描述為"姓名",這樣,當 txtName_.Text 是空值時提交資料,將會彈出提示"姓名不可為空".而Id則規定了要輸入現在新身份證的格式,如果不符合的話則提示"社會安全號碼碼格式不正確".另外,Sex是個自訂的類.得做個針對他的TypeConverter,然後給Sex類加上TypeConverterAttribute才可能被正確的處理.

    public class Person
    {
        public Person()
        {
                
        }

        string _name;
        decimal _height;
        DateTime _birthday;
        Sex _sex;
        [Validate(AllowNull = false, Description = "姓名")]
        public string Name 
        {
            get {return _name;}
            set {_name = value;}
        }
        [Validate(Description = "身高")]
        public decimal Height
        {
            get {return _height;}
            set {_height = value;}
        }
        string _id;
        [Validate(RegEx = "^\\d{17}(\\d|x)$", Description = "社會安全號碼碼")]
        public string Id 
        {
            get {return _id;}
            set {_id = value;}
        }
            
            public DateTime Birthday
        {
            get {return _birthday;}
            set {_birthday = value;}
        }

        public Sex Sex 
        {
            get {return _sex;}
            set {_sex = value;}
        }
    }

在使用Person類時,一行語句就能實現控制項和資料間賦值.以下是一個aspx後台代碼的片斷:
        Person p = new Person();
        BindingManager bm = new BindingManager();
        private void Page_Load(object sender, System.EventArgs e)
        {

            if (!IsPostBack) 
            {
                //validateForm()是用戶端驗證控制項合法性時調用的函數                       
                Button1.Attributes["onclick"] = "return validateForm();"; 
                //給p隨便設點值
                p.Name = "Yok";
                p.Height = 170;
                p.Sex = Sex.Male;
                p.Birthday = new DateTime(1980, 11, 21);
                //這樣就可以讓控制項顯示p的內容                
                bm.GetEntityValues(Page, p);
            }
        }

        private void Button1_Click(object sender, System.EventArgs e)
        {
            //把值賦給實體
            bm.SetEntityValues(Page, p);
            //這時p已經從控制項獲得各個屬性的值.Write出來看一下是否正確
            Response.Write("Name = " + p.Name + "<br>");
            Response.Write("Height = " + p.Height + "<br>");
            Response.Write("Birthday = " + p.Birthday.ToShortDateString() + "<br>");
            Response.Write("Id = " + p.Id + "<br>");
            Response.Write("Sex = " + p.Sex.ToString() + "<br>");
        }

不說了,My Code應該比我的文字好懂

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.