5.模型

 

 

 

 

模型的概念

模型这个词在软件开发领域被多次引用,代表数百种不同的概念,如成熟度模型,设计模型,威胁模型和进程模型等。这里讨论的是数据库中执行业务计算并在视图中渲染的模型对象,这些对象代表着应用程序关注的域,模型就是要显示,保存,创建,更新和删除的对象。

  个人理解:把数据库中的数据取出持久化,在程序中经过运算,再通过实体的变化修改数据库的数据。

1)模型的创建

首先在sql2008建好了数据表

Materiel物料表,Warehouse仓库表,TransactionRecord进出仓操作表,WarehouseBalance仓库余额表。

 

每个表的字段和约束关系

 

创建模型使用了Entity Framework(EF)微软以ADO.NET为基础发展出来的对象关系对应(OR Mapping)解决方案。

新建mvc项目,然后右键Models文件夹,添加-类,在弹出框中一步步根据sql2008数据库中的字段生成实体模型。

 

 

完成后,Models文件夹里面多了五个类文件,Model1继承DbContext

 

DbContext 实例表示工作单元和存储库模式的组合,可用来查询数据库并将更改组合在一起,这些更改稍后将作为一个单元写回存储区中。DbContext 在概念上与ObjectContext 类似。

 

其他就是普通的实体类了,注意如果为主键,需要在上方标识[Key],”id”默认标识为key

 

3)强类型视图增删查改

在MaterielController写入Add action方法,新建Materiel对象,通过return view的第一个参数传到Add视图,新建Add视图。

newModel1对象。

Addpost方法,FormCollection可以接收form表单提交的值。用form[“xx”]取出。

然后把获取到的值填充到Materiel模型类,通过db.Materiel.Add(实体);添加到上下文。

db.SaveChanges();保存到数据库。

添加MaterielController add actionview视图。

开头using模型和声明具体的模型,8-12行则通过viewbag的值来判断来生成两个链接。

@Html.LabelFor@Html.TextBoxFor这些强类型的辅助方法,参数传入的是lambda表达式。好处是可以.出来字段。Model.id就可以读出头部@model模型id的值。

运行,地址栏输入/Materiel/Add

输入测试数据,提交。

获取到数据后保存到数据,然后给ViewBag.success赋值,再次进入add view。根据条件显示了成功。

打开sql sever2008 r2。查看Materiel表的数据。

成功添加数据。

要在数据库看数据麻烦,新建一个可以看数据的action

ToList可以把数据以list的形式返回。然后传到对应的view页面。

添加list actionview页面。

 

利用循环获取实体中字段的值。后面加上两个a标签,地址是所在控制器对应的修改和删除方法,并带上参数

 

运行,地址栏输入/Materiel/List。成功显示数据。

 

根据数据的条数table行循环了6次。

 

上图的编辑超链接指向了

/Materiel/Edit/Materiel/Del方法,还带上了id的值。

添加获取Get访问的 Edit action。通过获取的id来查询数据库中表Materiel Id = 所传id的那条数据,把数据传到所在的view页面。添加view页面。

 

模型数据传过来后会自动绑在Html辅助方法生成的控件上。然后点击提交按钮,用post提交到/Materiel/Edit

 

添加提交post访问的 Edit action。可以在方法参数内写入提交的模型,会自动为这个模型赋上提交的值。

先查询出id符合的数据是否还存在,不存在返回错误页面,存在侧改变字段值,进行保存,返回list列表查询界面。

运行,地址栏输入/Materiel/List。选择一条数据,点击编辑。

 

数据展示后,把文本框的值修改一下。提交。

 

返回到list界面。数据修改成功。

 

再次修改第一条数据,这时在提交之前在数据库中手动删除该数据。

再提交数据。数据已经删掉,所以无法修改,转到错误页面。

 

添加Del action。取得超链接传来id的值,先查询是否有数据,有则删除后返回列表,无则返回错误页面,此action无须新建view

 

运行,地址栏输入/Materiel/List/。先在数据库中手动删除”可乐”的数据。

 

再在页面没刷新的情况下点击”可乐”的删除链接,提示失败,因为数据已经没有了。

 

现在正常删除一条新添加的”药”的数据。

 

删除成功。

 

 

4)自定义模型绑定

如图,前台数据会自动绑定到模型Materiel,传到控制器方法。但是不太安全,有时候我们只需要接收几个字段的指。

 

我们可以用Include来决定要接收绑定的指。

 

现在只接收id,MaterielNo,MaterielName 3个字段的指。运行程序输入/Materiel/List。

 

编辑”水杯”的数据。进入编辑页面后直接点击提交按钮。

在调试模式下。看到Materiel实体中只对id,MaterielNo,MaterielName 3个字段绑定数据,Company和Price为null。

 

[Bind(Exclude = "Company,Price")]是排除模型内字段的写法。也可以达到同样的效果。

 

写在模型类上方,效果一样。

 

如果参数和类上都用了Bind特性绑定,则取交集。

 

定制自定义绑定

新建文件夹MyModelBinders。里面新建一个Binder类。

Binder实现IModelBinder接口BindModel方法。当处理Materiel模型绑定时会进入,获取Price数量并+10,返回模型。

 

启动此定制自定义模型绑定需要在Global.asax.cs文件下写入注册代码。

 

运行程序地址栏输入/Materiel/List ,点击”水杯”的编辑链接,进入编辑页面后直接提交。

 

“Price”原本为50,现在变成了60

 

 

5)ModelState验证输入

验证输入用到了@Html.ValidationSummary()显示总体错误@Html.ValidationMessage()显示一条错误信息。

@Html.ValidationSummary()第一个参数为true,我们只需要显示模型级错误。

@Html.ValidationMessage()第一个参数填入了需要验证的模型字段。

/Materiel/Add视图修改如下。

Post Add方法修改成参数获取模型绑定的方式。当Materiel实体没有提交MaterielNo字段值时,就向ModelState添加一条模型错误信息 this.ModelState.AddModelError("MaterielNo", "物料编号必须填写");第一个参数是模型字段值,第二个参数是错误的信息。当ModelState存有错误信息时ModelState.IsValid==false,直接返回视图。

回到提交错误的页面,文本框重新取得model的数据。并展示@Html.ValidationSummary(),@Html.ValidationMessage()的错误信息。

运行程序,地址栏输入/Materiel/Add,填入除MaterielNo的其他数据,提交。使其触发错误。

 

提交后两个错误信息显示,且无法提交的数据没有因为页面的刷新而丢失。

 

错误产生的元素,css样式可以自己修改。

 

 

模型特性验证Attrinute

ModelState验证通过代码进行验证,Attrinute验证可直接在模型上输入特性来验证,更清晰明了。

先修改Add post方法,方便测试。

 

View页面。

 

[DisplayName("")]可用于给字段赋予要显示的名称。

 

添加完各个属性字段的[DisplayName("")]后,运行程序,地址栏输入/Materiel/Add。字段变成了DisplayName输入的文字。Add View可以显示DisplayName输入的文字。

 

[Required]表明字段必须填写

 

添加完各个属性字段的[Required]后,运行程序,地址栏输入/Materiel/Add。提交。看到了错误的提示。

 

[StringLength()]可以规定属性字段可输长度范围。

 

第一个参数5代表最大长度,MinimumLength最小长度,ErrorMessage错误信息。占位符{0}代表DispayName的名称(没有则是MaterielNo),{2}代表MinimumLength的值,{1}代表5。运行程序,地址栏输入/Materiel/Add,在MaterielNo输入框输入“123456”提交。

 

[RegularExpression()]可以输入正则表达式限制提交数据规则。

第一个字符串参数输入的时正则表达式,第二个参数是验证错误时的错误信息。

运行程序,地址栏输入/Materiel/Add,在MaterielNo输入框输入“我的程序”提交。显示错误信息。

 

[Range()]可以控制输入数字在某大小段之间。第一个参数是最小值,第二个参数是最大值,第三个参数是验证错误时的错误信息。运行程序,地址栏输入/Materiel/Add,在MaterielNo输入框输入“10001”提交。显示错误信息。

 

Range还可以声明为DateTime类型来限定输入的日期范围。

[Range(typeof(DateTime),”1990/1/1”,”1999/1/1”)]

 

[Compare()]可以验证两个输入框输入的数据是否一致。第一个参数表明要和属性字段”MaterielNo”输入一致,第二个参数是验证错误时的错误信息。运行程序,地址栏输入/Materiel/Add,在MaterielNo输入框输入“123”,在MaterielName输入框输入”234”提交。显示错误信息。

 

 

6)客户端验证

上面的验证需要提交到服务器action方法处理,降低了效率。这里可以通过jquery.validate,jquery.validate.unobtrusive来完成客户端的验证,验证通过后再提交到服务器,大大提高效率。客户端验证需要配合模型特性验证Attrinute来使用。

右键项目名称,管理NuGet程序包。

 

在搜索栏找到jquery.validate和unobtrusive,点击右边的安装。

安装完毕后在页面地步引入js文件。

 

同时,项目的Web.config文件中,

    <add key="ClientValidationEnabled" value="true" />

<add key="UnobtrusiveJavaScriptEnabled" value="true" />

value改为"true",默认为"true"。

运行程序,地址栏输入/Materiel/Add,在post  Add  action方法中加入调试端点。

 

直接点击提交,没有进入post add action方法,但完成了验证。

 

 

posted @ 2017-10-08 22:47  飞天阿豪  阅读(181)  评论(0编辑  收藏  举报