不积跬步,无以致千里;不积小流,无以成江海

导航

实现WebForm下面的自动收集对象属性(与MVC下在的UpdateFrom一样)

23:15:57     对ASP.net MVC有了解的同学估计都对里面的UpdateFrom方法有较深的印象。它接受一个对象参数,然后,它会对任何匹配该对象的公开属性,自动对本身进行属性赋值。这样的功能都引来一片叫好声。可惜的是他只能在MVC下使用。那么在WebForm下面就不能实现这样的功能了吗?答案是可以的,其实还可以做得更好。这里把以前的代码翻出来晒晒。
    我们还是先看一下UpdateFrom的实现。其实实现很简单,就是先用反射取得对象的所有的属性。然后在Requet.QuerySting或Requet.Form中查找对应的键。如果 找到了对应的值就再调用Property.SetValue方法对其设置属性值。代码如下
UpdateFrom
   下面进入正题。看看在Webform下面的实现,思路还是一样的。先把我的实现代码贴上来再说
    /// <summary>
    
/// 根据对象自动给相应控件取值或者赋值
    
/// </summary>

    public class ValuePicker
    
{
        
/// <summary>
        
/// 把对象赋值给相应控件
        
/// </summary>
        
/// <param name="dataEntity">对象</param>
        
/// <param name="page">要搜索控件的Page或者Master里的ContentPlaceHolder</param>
        
/// <returns></returns>

        public int SetValue(object dataEntity, Control page)
        
{
            
return OperateValue(dataEntity, page, true);
        }

        
/// <summary>
        
/// 把相应控件的属性值赋给对象的相应属性
        
/// </summary>
        
/// <param name="dataEntity">对象</param>
        
/// <param name="page">要搜索控件的Page或者Master里的ContentPlaceHolder</param>
        
/// <returns></returns>

        public int GetValue(object dataEntity, Control page)
        
{
            
return OperateValue(dataEntity, page, false);
        }

        
/// <summary>
        
/// 根据每个控件的类型,获取对应操作的属性名称
        
/// </summary>
        
/// <param name="typeName">控件类型</param>
        
/// <returns></returns>

        private string GetPropertyTypeName(string typeName)
        
{
            
switch (typeName)
            
{

                
case "TextBox":
                    
return "Text";
                
case "DropDownList":
                    
return "SelectedValue";
                
case "CheckBox":
                    
return "Checked";
                
case "HiddenField":
                    
return "Value";
                
default:
                    
return "Text";
            }

        }

        
/// <summary>
        
/// 具体实现赋值和取值的方法
        
/// </summary>
        
/// <param name="dataEntity">对象</param>
        
/// <param name="page">要搜索控件的Page或者Master里的ContentPlaceHolder</param>
        
/// <param name="isSetting">是否是要设置控件的值</param>
        
/// <returns></returns>

        private int OperateValue(object dataEntity, Control page, bool isSetting)
        
{
            
try
            
{
                Type EntityType 
= dataEntity.GetType();
                Type ControlType;
                
//取得所有的属性
                PropertyInfo[] Pinfos = EntityType.GetProperties(); ;
                Control Ctrl;
                Object Data 
= null;
                
string PropertyTypeName;
                
//遍历所有的属性
                foreach (PropertyInfo Pinfo in Pinfos)
                
{
                    
//查找属性对应的控件
                    Ctrl = page.FindControl(Pinfo.Name);
                    
if (Ctrl != null)
                    
{
                        ControlType 
= Ctrl.GetType();
                        
//取得控件存储值的属性
                        PropertyTypeName = GetPropertyTypeName(ControlType.Name);
                        
                        
if (isSetting == true)
                        
{//把对象的值设置给控件
                            Data = EntityType.InvokeMember(Pinfo.Name,
                             BindingFlags.GetProperty, 
null, dataEntity, null);
                            Data 
= ReDefineData(ControlType,Data, PropertyTypeName); 
                            
object[] SettingData ={ Data };
                            ControlType.InvokeMember(PropertyTypeName,
                           BindingFlags.SetProperty, 
null, Ctrl, SettingData);
                        }

                        
else
                        
{//取得控件的值赋给对象对应的属性
                            Data = ControlType.InvokeMember(PropertyTypeName,
                            BindingFlags.GetProperty, 
null, Ctrl, null);
                            Data 
= ReDefineData(EntityType, Data, Pinfo.Name);

                            
object[] SettingData ={ Data };
                            EntityType.InvokeMember(Pinfo.Name,
                            BindingFlags.SetProperty, 
null, dataEntity, SettingData);
                        }

                    }

                }

                
return 0;
            }

            
catch (System.Exception E)
            
{
                System.Diagnostics.Debug.WriteLine(E.ToString());
                
//注意
                throw (E);
                
return -1;
            }

        }


        
/// <summary>
        
/// 进行数据类型转换
        
/// </summary>
        
/// <param name="controlType"></param>
        
/// <param name="data"></param>
        
/// <param name="PropertyTypeName"></param>
        
/// <returns></returns>

        private object ReDefineData(Type controlType,Object data, string PropertyTypeName)
        
{
            
if (data == null)
                
return null;
            
switch (controlType.GetProperty(PropertyTypeName).PropertyType.Name)
            
{
                
case "Boolean":
                    
if ((int)data == 1)
                        data 
= true;
                    
else
                        data 
= false;
                    
break;

                
case "String":
                    data 
= data.ToString();
                    
break;
                
case "Int32":
                    data 
= Convert.ToInt32(data);
                    
break;
                
case "Double"
                    data 
= Convert.ToDouble(data);
                    
break;
                
default:
                    
break;
            }

            
return data;
        }

    }
GetPropertyTypeName里面的类型还不够多。比如如果你用到了RadioButtonList,你可以自己加上对应的属性SelectedValue,在这里就只列这么多了。你可以自己改成更好的实现方法。另外ReDefineData应该也要相应的添加一些对应关现。在看了UpdateFrom的实现以后,其实这个类异常的处理应该要改成UpdateFrom才更好,这里就不改了,有空的话我会再改进一下。
另外你还可以写一个类以方便调用

PageUtility



posted on 2008-02-20 00:51  Dream.Lee  阅读(2279)  评论(6编辑  收藏  举报