• 模拟MVC-WebForm实现ModelBinding


    (一) 前言                                                                          

    用ASP.NET MVC的时候,我们都知道在提交表单的时候可以自动模型绑定到对应的实体上,这样开发者就不需要手动将表单数据转换成对应的model了。

    然而,在WebForm中没有提供现成的方法让我们自动绑定模型,所以,我就通过反射写了一个泛型方法进行自动的模型绑定,同时还提供基本的数据验证。

    (二) 编写ModelBinding方法                                                      

    我们在BasePage类(此类继承自System.Web.UI.Page)中编写ModelBing方法。

    代码如下:

     1 #region 模型绑定
     2         //模型绑定的错误消息
     3         public Dictionary<string, string> ErrorMsgs = new Dictionary<string, string>();
     4         //是否验证通过
     5         public bool IsValidated { get; set; }
     6         /// <summary>
     7         /// 手写模型绑定器--添加编辑数据时使用--对数据的验证不是很精确,主要还要依赖前台验证
     8         /// </summary>
     9         /// <typeparam name="T"></typeparam>
    10         /// <returns></returns>
    11         public T ModelBinding<T>(params T[] entityP)
    12         {
    13 
    14             object entity = Activator.CreateInstance(typeof(T));//添加
    15             if (entityP != null && entityP.Length > 0)//编辑
    16             {
    17                 entity = entityP[0];
    18             }
    19             Type types = entity.GetType();
    20             var pros = types.GetProperties();
    21             Dictionary<string, System.Reflection.PropertyInfo> proNames = new Dictionary<string, System.Reflection.PropertyInfo>();
    22             foreach (var p in pros)
    23             {
    24                 proNames.Add(p.Name, p);
    25             }
    26             var forms = Request.Form;
    27             var keys = forms.AllKeys;
    28             foreach (var key in keys)
    29             {
    30                 if (proNames.Keys.Contains(key))
    31                 {
    32                     var pro = proNames[key];
    33                     var type = pro.PropertyType;
    34                     var columnValue = forms[key];
    35                     if (string.IsNullOrEmpty(columnValue))//数据表列值不为空
    36                     {
    37                         continue;
    38                     }
    39                     try
    40                     {
    41                         if (type.IsEnum)//若果属性是枚举类型
    42                         {
    43                             pro.SetValue(entity, Enum.ToObject(type, columnValue), null);
    44                         }
    45                         else
    46                         {
    47                             if (type.IsGenericType && type.Name.StartsWith("Nullable"))//泛型类型
    48                             {
    49                                 type = Nullable.GetUnderlyingType(type);
    50                             }
    51                             pro.SetValue(entity, Convert.ChangeType(columnValue, type), null);
    52 
    53                         }
    54                     }
    55                     catch (Exception ex)
    56                     {
    57                         ErrorMsgs.Add(key, ex.Message);
    58                     }
    59                 }
    60             }
    61             IsValidated = ErrorMsgs.Count > 0 ? false : true;
    62             return (T)entity;
    63         } 
    64         #endregion

    说明:上述代码利用反射、泛型实现了简单的模型绑定和数据非法性的验证。

            其中,表单数据的name必须和数据库表对应的列名一致。

    (三) 表单aspx页面的约束                                                     

    说明:表单数据的验证先在前台通过validate.js验证一遍,然后在服务端再次自动验证一遍。

           因为是模拟ASP.NET MVC进行的模型绑定,所以在此页面上就完全不需要服务端控件了,这也极大的提高服务器了性能。

           表单页面代码如下:

      1 <%@ Page Language="C#" AutoEventWireup="true" ValidateRequest="false" CodeFile="NoticeEdit.aspx.cs" Inherits="Information_NoticeEdit" %>
      2 
      3 <!DOCTYPE html>
      4 
      5 <html xmlns="http://www.w3.org/1999/xhtml">
      6 <head id="Head1" runat="server">
      7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      8     <title></title>
      9     <%--基础样式--%>
     10     <link rel="stylesheet" type="text/css" href="../Styles/admin-all.css" />
     11     <link rel="stylesheet" type="text/css" href="../Styles/base.css" />
     12     <link rel="stylesheet" type="text/css" href="../Styles/formui.css" />
     13     <link href="../Styles/ui-lightness/jquery-ui-1.8.22.custom.css" rel="stylesheet" />
     14 
     15     <script src="../Scripts/JQuery/jquery-1.7.2.min.js"></script>
     16     <script src="../Scripts/JQuery/jquery-ui-1.8.22.custom.min.js"></script>
     17     <%--表格特效--%>
     18     <script src="../Scripts/tb.js"></script>
     19 
     20 
     21     <!--JBOX弹出插件-->
     22     <script src="../Scripts/JBox/jquery.jBox-2.3.min.js" type="text/javascript"></script>
     23     <!--JBOX弹出插件样式-->
     24     <link href="../Scripts/JBox/Skins/Blue/jbox.css" rel="stylesheet" type="text/css" />
     25     <!--JBOX全局默认值-->
     26     <script src="../Scripts/JBox/i18n/jquery.jBox-zh-CN.js" type="text/javascript"></script>
     27 
     28     <!--验证-->
     29     <link href="../Scripts/validate/validate.css" rel="stylesheet" />
     30     <!--验证-->
     31     <script src="../Scripts/validate/jquery.validate.js"></script>
     32     <!--汉化验证信息-->
     33     <script src="../Scripts/validate/messages_cn.js"></script>
     34     <!--日期控件-->
     35     <%--<script src="../Scripts/My97DatePicker/WdatePicker.js"></script>--%>
     36     <%--kindeditor--%>
     37      <link href="../Scripts/kindeditor-4.1.10/themes/default/default.css" rel="stylesheet" />
     38     <script src="../Scripts/kindeditor-4.1.10/kindeditor-min.js"></script>
     39     <script src="../Scripts/kindeditor-4.1.10/lang/zh_CN.js"></script>   
     40     <script type="text/javascript">
     41         $(function () {
     42             var vForm = $("#form1").validate({
     43                 errorElement: "span",
     44                 rules: {
     45                     Title: {required:true,maxlength:64},
     46                     Contents: {required:true,maxlength:64},
     47                     AddUserName: {required:true,maxlength:16},     
     48                     FromWhere: { required: true,maxlength:64 },
     49                     Sort: {digits:true},                   
     50                     Remark: { maxlength: 256 }
     51 
     52                 },
     53                 messages: {
     54                     Title: {required:"必填信息",maxlength:"最大长度64"},
     55                     Contents: {required:"必填信息",maxlength:"最大长度64"},
     56                     AddUserName: {required:"必填信息",maxlength:"最大长度16"},
     57                     FromWhere: {required:"必填信息",maxlength:"最大长度64"},
     58                     Sort: {number:"必须是整数"},
     59                     Remark: { maxlength: "最大长度256" }
     60                   
     61                 }
     62             });
     63         })
     64 
     65         var content = null;
     66         KindEditor.ready(function (K) {
     67             content = K.create("#Contents", {
     68                 cssPath: '../kindeditor-4.1.10/plugins/code/prettify.css',
     69                 uploadJson: '../kindeditor-4.1.10/asp.net/upload_json.ashx',
     70                 fileManagerJson: '../kindeditor-4.1.10/asp.net/file_manager_json.ashx',
     71                 allowFileManager: true,
     72                 afterCreate: function () {
     73                     this.sync();
     74                 },
     75                 afterBlur: function () {
     76                     this.sync();
     77                 }
     78             });
     79             prettyPrint();
     80         });
     81         
     82     </script>     
     83     
     84 </head>
     85 <body>
     86     <form id="form1" runat="server">
     87         <div class="alert alert-info">当前位置<b class='tip'></b><%=ListTitle %></div>
     88         <%-- 刷新返回--%>
     89         <table class="tb">
     90             <tr height="45">
     91                 <th>
     92                     <input type="button" class="btn" onclick='window.location.href=window.location.href;' value="刷新" />
     93                     &nbsp;&nbsp;
     94                     <input type="button" class="btn" onclick='window.location.href="<%=ListUrl %>    ";' value="返回" />
     95                 </th>
     96             </tr>
     97         </table>
     98 
     99         <%--表单--%>
    100         <table class="tbform">
    101             <tbody>
    102 
    103                 <tr height="38">
    104                     <td class="tdl" width="80">标题</td>
    105                     <td class="detail">
    106                         <input type="text" id="Title" name="Title" value='<%=entity.Title %>'  class="required width300 " />
    107                     </td>
    108                 </tr>
    109                 <tr height="38">
    110                     <td class="tdl">内容</td>
    111                     <td class="detail">
    112                         <textarea   name="Contents" id="Contents"  style="670px;height:350px;visibility:hidden;" ><%=entity.Contents %></textarea>
    113                     </td>
    114                 </tr>
    115                 <tr height="38">
    116                     <td class="tdl">作者</td>
    117                     <td class="detail">
    118                         <input type="text" id="AddUserName" name="AddUserName" value='<%=entity.AddUserName %>' class="required width300"  />
    119                     </td>
    120                 </tr>         
    121                  <tr height="38">
    122                     <td class="tdl">来源</td>
    123                     <td class="detail">
    124                         <input type="text" id="FromWhere" name="FromWhere" value='<%=entity.FromWhere %>' class="required width300"  />
    125                     </td>
    126                 </tr>         
    127                 <tr height="38">
    128                     <td class="tdl">排序</td>
    129                     <td class="detail">
    130                         <input type="text" id="Sort" name="Sort"  value='<%=entity.Sort==null?"50":entity.Sort.Value.ToString() %>' class="ipt width300"   />
    131                     </td>
    132                 </tr>       
    133                 <tr height="38">
    134                     <td class="tdl">备注</td>
    135                     <td class="detail">
    136                         <textarea id="Remark" name="Remark"  cols="48" rows="5"><%=entity.Remark %></textarea>
    137                     </td>
    138                 </tr>
    139             </tbody>
    140         </table>
    141 
    142         <%--提交返回--%>
    143         <table class="tb">
    144             <tr height="45">
    145                 <th align="left">
    146                     <input class="btn btn-success" id="find" type="submit" value="提交" />
    147                     &nbsp;&nbsp;
    148                      <input type="button" class="btn" onclick='window.location.href="<%=ListUrl %>    ";' value="返回" />
    149                 </th>
    150 
    151             </tr>
    152         </table>
    153         <input type="hidden" id="hiddenId" name="hiddenId"  value='<%=entity.Id==0?"":entity.Id.ToString() %>' />
    154     </form>
    155 </body>
    156 </html>
    aspx页面代码

    (四) 表单后台的自动添加修改                                                    

    说明:由于是实现模型的自动绑定,所以就不能再手动的进行表单的组装了,通过下面可以看到,再也没有事件驱动了,表单数据也清爽了很多。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Web;
     5 using System.Web.UI;
     6 using System.Web.UI.WebControls;
     7 
     8 public partial class Information_NoticeEdit : WebBase.BasePage
     9 {
    10     protected string ListTitle = "信息管理<b class='tip'></b>公告编辑";
    11     protected string EditUrl = "NoticeEdit.aspx";
    12     protected string ListUrl = "NoticeList.aspx";
    13     protected BLL.Info_NoticeBLL bll = BLL.BLLSession.Info_NoticeBLL;//当前数据访问网关
    14     protected Model.Info_Notice entity = null;
    15     protected void Page_Load(object sender, EventArgs e)
    16     {
    17         //权限验证
    18         CheckUserPermission("NoticeManager", WebBase.BaseEnum.ActionEnum.View);
    19         if (!IsPostBack)
    20         {
    21             LoadData();
    22         }
    23         else
    24         {
    25             if (!string.IsNullOrEmpty(GetFormString("hiddenId")))
    26             {
    27                 ModifyData();
    28             }
    29             else
    30             {
    31                 AddData();
    32             }
    33         }
    34     }
    35 
    36     //修改时加载数据
    37     protected void LoadData()
    38     {
    39         entity = bll.GetEntityById(GetQueryInt("id"));
    40         if (entity == null)
    41         {
    42             entity = new Model.Info_Notice();
    43         }
    44        
    45     }
    46 
    47     //添加数据
    48     protected void AddData()
    49     {
    50         //添加时,模型绑定
    51         entity = ModelBinding<Model.Info_Notice>();
    52         entity.AddUser = GetUser().Id;
    53         entity.AddTime = DateTime.Now;
    54         entity.Deleted = false;       
    55 
    56         if (IsValidated&&bll.AddEntity(entity))
    57         {
    58             ShowJbox("添加成功", ListUrl, "success");
    59         }
    60         else
    61         {
    62             ShowJbox("添加失败", "error");
    63         }
    64 
    65     }
    66     //修改数据
    67     protected void ModifyData()
    68     {
    69         entity = bll.GetEntityById(GetFormInt("hiddenId"));
    70         //修改时,模型绑定
    71         entity = ModelBinding<Model.Info_Notice>(entity);        
    72         entity.ModUser = GetUser().Id;
    73         entity.ModTime = DateTime.Now;
    74         if (IsValidated && bll.ModifyEntity(entity))
    75         {
    76             ShowJbox("修改成功", ListUrl, "success");
    77         }
    78         else
    79         {
    80             ShowJbox("修改失败", "error");
    81         }
    82     }
    83 }

    (五) 运行演示                                                   

    1.列表页面如下:

    2.添加编辑页面如下:

    3.添加 成功如图:

     (六) 小结                                                  

    以上叙述,就完成了在webform中的模型绑定功能的实现。如有错误或者不妥之处,欢迎指正。

  • 相关阅读:
    个人学习jQuery笔记
    (转载) jQuery页面加载初始化的3种方法
    [转]学会和同事相处的30个原则
    解决iis出现这个问题-2147467259 (0x80004005)
    不规则瀑布流图片墙
    实现图片大小的自动控制( 图片大小控制CSS代码)
    (转载)DataTable使用技巧总结
    (转载) jQuery 页面加载初始化的方法有3种
    ajax连接数据库并操作数据库
    java Semaphore实现ABC三个线程循环打印
  • 原文地址:https://www.cnblogs.com/eggTwo/p/3762261.html
Copyright © 2020-2023  润新知