ASP.NET没有魔法——ASP.NET MVC 模型绑定
在My Blog中已经有了文章管理功能,可以发布和修改文章,但是对于文章内容来说,这里缺少最重要的排版功能,如果没有排版的博客很大程度上是无法阅读的,由于文章是通过浏览器查看的,所以文章的排版其实与网页的排版一致,是通过HTML+CSS实现的,但是在一个输入框中写文章内容还有HTML+CSS是不现实的,所以本文将使用ueditor编辑器来实现排版功能,并通过该功能为引介绍ASP.NET MVC中的模型绑定。
本章主要内容有:
● ueditor的下载与安装
● 在页面上使用ueditor
● ASP.NET MVC模型绑定简介
● ASP.NET MVC不同数据类型的模型绑定
○ 基本类型
○ 自定义类型
○ 数组
○ 简单对象数组
○ 自定义类型字典
○ 包含数组的自定义类型
○ 多种数据源的数据获取
○ Bind特性
○ 结论
● 小结
ueditor的下载与安装
ueditor是一个百度开源的web编辑器,其功能非常强大并且还针对不同语言提供了对应的后台程序用于支持图片、文件的上传、网络图片抓取等。先下载ueditor,并将其添加到My Blog项目中的Scripts文件夹下:
1、下载:http://ueditor.baidu.com/website/download.html
注:本例使用[1.4.3.3 .Net 版本]
上图就是ueditor的目录结构:
● net目录保存了使用.net实现了后台文件处理的相关代码实现。
● ueditor.all.js是ueditor的主文件,在使用编辑器时要引入该文件。
● ueditor.config是编辑器的js配置文件,使用时也需要引入该文件。
上图是net目录下的文件信息:
● App_Code存放了相关功能的逻辑处理代码。
● config.json是后端程序的配置信息,编辑器初始化时首先会读取该配置。
● controller.ashx编辑器与后台交互的接口,包括配置信息的读取、图片文件的上传等。
注:ueditor提供了一个可以独立部署的.Net程序,如果要独立部署可参考文档http://fex.baidu.com/ueditor/#server-net
另外如果ueditor提供的后台处理程序不能满足需求时可参照其源码自己实现即可,本例使用默认提供的代码来完成。
2、完成ueditor图片上传等相关后台功能配置:
在默认的imageUrlPrefix的签名加上“/scripts/”,因为上传功能是以controller.ashx所在路径在拼接上imagePathFormat配置的路径确定的文件上传路径和文件名称,所以在访问图片时需要加入controller.ashx所在路径。
同理由于ueditor提供了网络图片抓取、视频、文件等上传功能,所以需要继续修改相关配置。
在页面上使用ueditor
1、在添加和更新文章页面加入js引用及初始化代码:
2、另外需要在PostMaintainViewModel的Content属性上加入AllowHtml特性,因为内容中包含HTML代码,验证会抛异常
下图是添加文章用的Insert方法:
注:ASP.NET 提供了请求验证的功能,它用于验证HTTP请求中是否包含危险内容,如HTML、JS等,所以如果要提交带有html的内容需要在相应的模型字段上使用AllowHtml特性或者在action上使用ValidateInput(false)特性来关闭请求验证,更多内容参考:https://msdn.microsoft.com/en-us/library/hh882339(v=vs.110).aspx
3、运行结果:
添加页面:直接复制一篇博客园的文章,粘贴到编辑器中。
查看页面:从图中可以看到该编辑器可以将原有的样式以及图片都复制过来,虽然样式上有一些小问题。
ASP.NET MVC模型绑定简介
ASP.NET MVC的模型绑定功能的作用是将Http请求中的数据映射到MVC的Action方法的参数上,上面介绍的内容就是利用MVC的模型绑定功能,将在HTML表单中填写的数据映射到Insert方法的PostMaintainViewModel类型参数上。
Action的参数一般为.Net的基本类型(int、float、char等)或者是自定义类型,除此之外还有基于这两种类型的数组、字典等。
而在ASP.NET MVC中一般通过queryString、FormData、RouteData等将数据提交到服务器,然后再根据一些特殊的规则完成数据的识别与绑定。下面将通过一系列的Demo来介绍不同数据源以及不同参数类型是如何绑定的。
ASP.NET MVC模型绑定方式
基本类型
1、 Query String:通过queryString的变量名称与action的变量名称匹配:
url:http://localhost:52356/ModelBinderTest/demo1?field=test111
执行结果:
2、FormData:在Html的Form中包含与action参数名匹配的的input标签:
url:http://localhost:52356/ModelBinderTest/demo2
页面代码和效果:
执行结果(点击提交按钮):
3、RouteData :在路由相关章节中介绍过,通过路由模板可以定义一些变量,当匹配到这些变量后会将其存放在RouteData中:
url:http://localhost:52356/ModelBinderTest/demo3/hello
路由配置:
执行结果:
ASP.NET MVC基本类型的绑定无论是从Query String、FormData还是RouteData,都是根据名称来匹配的,如果上面的demo修改了参数名称,那么将无法获得数据。除了基类类型其它的自定义类型、数组等都是以名称匹配为主要手段,并且它们都是以Query String、Form Data以及Route Data为主要数据源,下面对自定义及数组等类型分析时将只通过Query String来作为数据源。
自定义类型
下图是该自定义类型的定义,只有两个字符串类型的属性:
1、通过属性名匹配对象字段名称:
url:http://localhost:52356/ModelBinderTest/Demo4?field1=test123&field2=111111
执行结果:
2、通过以参数名称为前缀匹配:
url:http://localhost:52356/ModelBinderTest/Demo4?obj.field1=test123&obj.field2=111111
执行结果:
3、通过参数名称为前缀区分不同对象:
url:http://localhost:52356/ModelBinderTest/Demo4?obj.field1=test123&obj.field2=111111&obj1.field1=hello&obj1.field2=world
执行结果:
对于简单的自定义类型来说,它可以直接使用参数对象的属性名称来匹配,或者通过参数名称作为前缀来指定,避免有多个参数对象存在属性同名。
数组
1、通过同名参数来绑定数组,其元素顺序按照参数顺序来决定:
url:http://localhost:52356/ModelBinderTest/demo5?fields=test111&fields=test222
执行结果:
2、通过添加数组索引来绑定数组,元素顺序与索引一致:
url:http://localhost:52356/ModelBinderTest/demo5?fields[1]=test111&fields[0]=test222
执行结果(注:绑定后的元素顺序与参数下标一致):
3、仅通过索引来绑定数组:
url:http://localhost:52356/ModelBinderTest/demo5?[1]=tes333&[0]=test222
执行结果(注:绑定后的元素顺序与参数下标一致):
简单对象数组
1、通过参数名及数组索引作为前缀来匹配参数中的属性:
url:http://localhost:52356/ModelBinderTest/Demo6?objs[0].field1=test123&objs[0].field2=111111&objs[1].field1=hello&objs[1].field2=world
执行结果:
2、仅通过索引作为前缀来匹配参数中的属性:
url:http://localhost:52356/ModelBinderTest/Demo6?[1].field1=test123&[1].field2=111111&[0].field1=hello&[0].field2=world
执行结果(注意顺序):
自定义类型字典
1、通过参数名称及其索引为前缀,Key、Value来分别关联字典中相应的值:
url:http://localhost:52356/ModelBinderTest/Demo7?objs[0].Key=1&objs[0].Value.field1=hello&objs[0].Value.field2=world
执行结果:
2、仅使用索引为前缀,Key、Value来分别关联字典中相应的值:
url:http://localhost:52356/ModelBinderTest/Demo7?[0].Key=1&[0].Value.field1=hello&[0].Value.field2=world&[1].Key=2&[1].Value.field1=hello1&[1].Value.field2=world1
执行结果:
包含数组的自定义类型
通过参数名称、属性名称、索引来完成绑定:
url:http://localhost:52356/ModelBinderTest/Demo8?obj.field1=hello&obj.field2=world&obj.simplyobjects[0].field1=hello1&obj.simplyobjects[0].field2=world1
执行结果:
多种数据源的数据获取
上面的例子均是以QueryString做为数据源来绑定数据,但是也提到过数据源除此之外还有FormData和RouteData,所以如果一个对象的数据分别位于多个数据源中,是否能够正常绑定呢?现在以绑定一个简单自定义对象为例,使用QueryString和RouteData为数据源查看对象的绑定结果:
url:http://localhost:52356/ModelBinderTest/Demo9/1/test123/?field2=111111
路由:
执行结果:
本例通过在路由模板中添加Field1变量信息来获取对象的Field1字段数据,然后从QueryString中获取了Field2字段数据,证明一个对象中的数据可以来自于不同的数据源。
但是在实际使用过程中建议只通过一个数据源获取数据,避免造成代码混乱难以管理。
Bind特性
它的作用是指明如何绑定模型的细节,比如前缀是什么,需要包含或排除的数据等等,其使用方式如下:
url:http://localhost:52356/ModelBinderTest/Demo10/1/?a.field1=test123&a.field2=111111
执行结果:
结论
1、用于模型绑定的数据源一般为QueryString、FormData和RouteData。
2、绑定基本类型时使用参数名称进行匹配。
3、绑定自定义类型时使用类型的属性名称匹配,可以使用参数名称作为前缀以区分name相同的变量。
4、绑定基本类型数组时可使用多个重复的参数名称来组件数组,也可以使用参数名称作为前缀,通过数组索引的形式指明数组某一位的元素的值是什么,当Action只有一个参数的时候也可以省略参数名称,直接使用数组索引来指明。
5、同一个参数的不同属性可以从不同的数据源中绑定。
注:在以上部分例子通过修改路由来满足调试需求,使用时需要注意。
小结
本文从一个内容添加功能引出了ASP.NET MVC中的模型绑定,并介绍了模型绑定的数据源以及针对不同数据类型的参数的绑定方式,模型绑定作为ASP.NET MVC的一项重要功能除了进行数值的绑定外还具有对绑定的值进行验证的功能,下一篇文章将对ASP.NET MVC中模型的验证进行介绍。