模拟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="width: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中的模型绑定功能的实现。如有错误或者不妥之处,欢迎指正。

模拟MVC-WebForm实现ModelBinding,布布扣,bubuko.com

时间: 2024-08-28 12:43:24

模拟MVC-WebForm实现ModelBinding的相关文章

MVC&amp;WebForm对照学习:文件下载

说完了WebForm和MVC中的文件上传,就不得不说用户从服务器端下载资源了.那么今天就扯扯在WebForm和MVC中是如何实现文件下载的.说起WebForm中的文件上传,codeshark在他的博文ASP.NET实现文件下载中讲到了ASP.NET中文件下载的4种方式.当然文章主要指的是在WebForm中的实现方式.总结得相当到位,那么这篇,就先来看看MVC中文件上传的方式.然后再回过头来看看它们实现方式的关联. Part 1 MVC中的文件下载 在mvc中微软封装好了ActionResult的

asp.net mvc webform和razor的page基类区别

接触过asp.net mvc的都知道,在传统的webform的模式下,page页面的基类是这样声明的: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage" %> 如果是partial view的话,则是这样声明的: <%@ Control Language="C#" Inherits=&q

springBoot单元测试-模拟MVC测试

1)模拟mvc测试,和基础测试是一样的, 都需要在pom文件中引入junit的支持. 略 2)编写测试类 Application1TestMVC 在类头上除啦加入之前的@RunWith(SpringRunner.class).@RunWith(SpringRunner.class) 之外还要加入新的注解 @AutoConfigureMockMvc // 注入MockMvc (当然你实在不想加也行,有其他办法 , 不过我不想说,麻烦) 1 package com.cx.springboot; 2

.net的WebForm模拟MVC进行模型绑定,让自己少操劳

用过MVC的兄弟们都知道,MVC有模型绑定表单提交的数据功能,那么我也想偷个懒也写个WebForm版的模型绑定.这里主要定义一个泛型方法,然后通过反射把表单上对应属性名字的值赋值到反射创建类的属性上. 有注意的地方: 1.定义的模型类的属性名要和表单name的名字相对应 2.定义的泛型方法是通过 var form = context.Request.Form;   表单 POST过来的数据 public class DataModel { /// <summary> /// 从表单提交的数据中

MVC&amp;WebForm对照学习:传值方式

刚从webform开发转到mvc,如果说像路由这样稍微复杂一点的知识点还可以暂时先放一放(前提是默认的路由规则基本满足大部分需求),那有个问题在快速开发中,我想是必须要当即解决的,那就是webform中的传值方式是否同样适用于mvc中.那么本文照旧分两部分来阐述.接下来先简单快速地回顾webform中的传值方式. Part 1  WebForm中的传值方式  Form表单传递(get/post)   //aspx<input type="text" id="txtNam

MVC&amp;WebForm对照学习:文件上传(以图片为例)

在web应用中,文件上传是个很普遍的功能,那么今天就来小结一下asp.net中文件上传的方式.首先我们快速来回忆一下WebForm中的文件上传的方法. Part 1 WebForm中的文件上传  FileUpload服务器控件 aspx: <div> <asp:Image ImageUrl="~/uploads/1.jpg" ID="img2" runat="server" Width="150px" Hei

Autofc与Mvc,WebForm,Weiapi,Owin整合源码分析

主要分析一下的几个项目: Autofac.Integration.Mvc Autofac.Integration.WebApi Autofac.Integration.Owin Autofac.Integration.Web Autofac.Integration.WebApi.Owin Autofac.Integration.Mvc.Owin 地址:https://github.com/autofac 以上几个项目分别是 Mvc Webapi Owin 和 webform 与autofac的整

MVC架构、WebForm与MVC对比

ylbtech-ASP.NET MVC:WebForm与MVC对比 功能描述:WebForm与MVC对比 A.1,MVC架构 •MVC(Model-View-Controller)用于表示一种软件架构模式.它把软件系统分为三个基本部分: –模型(Model) •引用系统数据,管理系统功能并通知View更改用户操作. –视图(View) •就是用户接口,用于显示数据 –控制器(Controller) •将用户操作映射到Model,并操作视图 A.2,3-Tier Architecture(三层架构

.Net MVC&amp;&amp;datatables.js&amp;&amp;bootstrap做一个界面的CRUD有多简单

我们在项目开发中,做得最多的可能就是CRUD,那么我们如何在ASP.NET MVC中来做CRUD呢?如果说只是单纯实现功能,那自然是再简单不过了,可是我们要考虑如何来做得比较好维护比较好扩展,如何做得比较漂亮.做开发要有工匠精神,不要只求完成开发任务,那样的话,永远停留在只是简单的写业务逻辑代码水平,我们要做有追求的程序员.本来这么简单的东西,我真是懒得写,但是看到即便是一些工作了好些年的人,做东西也是只管实现功能,啥都不管,还有些界面css样式要么就硬编要么就毫无规则的在页面中进行穿插,遇到要

简单谈谈js中的MVC

MVC是什么? MVC是一种架构模式,它将应用抽象为3个部分:模型(数据).视图.控制器(分发器). 本文将用一个经典的例子todoList来展开(代码在最后). 一个事件发生的过程(通信单向流动): 1.用户在视图 V 上与应用程序交互 2.控制器 C 触发相应的事件,要求模型 M 改变状态(读写数据) 3.模型 M 将数据发送到视图 V ,更新数据,展现给用户 在js的传统开发模式中,大多基于事件驱动的: 1.hash驱动 2.DOM事件,用来驱动视图 3.模型事件(业务模型事件和数据模型事