ASP.NET MVC学习之模型绑定(1)
一.前言
下面我们将开始学习模型绑定,通过下面的知识我们将能够理解ASP.NET MVC模型的模型绑定器是如何将http请求中的数据转换成模型的,其中我们重点讲述的是表单数据。
二.正文
1.简单类型绑定
学过一定ASP.NET MVC都会为这个特点所骄傲,就是能够将表单中与同名的参数映射,这相比操作ASP.NET控件来获取值轻便了许多,但是正如上面所说的那样要同名(大小写不区分),下面我们会讲述如何自己去指定。
首先我们在HomeController(如果不存在则创建)中获取表单中的值并显示:
1 namespace MvcStudy.Controllers 2 { 3 public class HomeController : Controller 4 { 5 public ActionResult Index() 6 { 7 return View(); 8 } 9 10 [HttpPost] 11 public ActionResult Index(String person) 12 { 13 TempData["msg"] = person ?? ""; 14 return View(); 15 } 16 } 17 }
接着我们在Views/Home/Index.cshtml中写入如下代码:
1 @{ 2 ViewBag.Title = "Index"; 3 } 4 5 @using (Html.BeginForm()) 6 { 7 <input type="text" name="perSon" /> 8 <input type="submit" value="submit" /> 9 } 10 11 @if (TempData.ContainsKey("msg")) 12 { 13 <p> 14 @TempData["msg"].ToString() 15 </p> 16 }
这里我们有一个name为perSon的输入框,下面我们在提交后还输出了这个值。下面读者可以尝试输入一个值,可以看到下面会对应的输出。但是这个时候我们将name为perSon的输入框改成persons就不会显示了。理由很简单,因为名称不同了,但是通过Bind注解属性可以解决这个问题,下面我们打开HomeController并修改代码:
1 [HttpPost] 2 public ActionResult Index([Bind(Prefix="persons")]String person) 3 { 4 TempData["msg"] = person ?? ""; 5 return View(); 6 }
这里我们通过Bind的Prefix修改了person的前缀,然后重新编译,我们可以发现又显示了。这样以后我们并不需要名称都一样了。
上面介绍的只是对于一个简单类型的情况,当然多的可以以此类推,但如果是数组呢?得益于ASP.NET MVC的默认模型绑定我们只要重复同一个name多次,就可以简单的形成了数组了比如我们将Index.cshtml改成如下代码:
1 @using (Html.BeginForm()) 2 { 3 <input type="text" name="persons" /> 4 <input type="text" name="persons" /> 5 <input type="text" name="persons" /> 6 <input type="text" name="persons" /> 7 <input type="text" name="persons" /> 8 <input type="text" name="persons" /> 9 <input type="submit" value="submit" /> 10 } 11 12 @if (TempData.ContainsKey("msg")) 13 { 14 <p> 15 @TempData["msg"].ToString() 16 </p> 17 }
作为演示我们只是简单的将输入框复制了几遍,下面我们修改HomeController的代码:
1 [HttpPost] 2 public ActionResult Index([Bind(Prefix="persons")]IList<String> person) 3 { 4 TempData["msg"] = String.Join(";", person); 5 return View(); 6 }
通过上面代码我们可以看到即使是数组一样也是可以使用Bind注解属性的,同时类型也改成了IList<String>,下面我们通过String的Join方法将这个数组拼接成一个数组,中间以分号分割。读者这个时候可以重新编译然后尝试,最后的效果如下所示:
2.复合类型绑定
很多实际的情况我们都会使用一个复合类型取代多个简单类型,那么问题就来了,ASP.NET MVC是如何绑定呢?对于一个复合类型,还是会按照名称映射到复合属性中对应的属性,但是好奇的人一定会使用Bind注解属性,想看看会发生什么事情,那么我们下面就 模拟一下,首先我们新建一个简单的Person类:
1 namespace MvcStudy.Models 2 { 3 public class Person 4 { 5 public String FirstName { get; set; } 6 public String LastName { get; set; } 7 public Address HomeAddress { get; set; } 8 } 9 }
还有一个Address类(后面需要使用):
1 namespace MvcStudy.Models 2 { 3 public class Address 4 { 5 public String Line1 { get; set; } 6 public String Line2 { get; set; } 7 } 8 }
接着我们修改Index.cshtml将其中的表单的输入框于Person对应起来:
1 @using (Html.BeginForm()) 2 { 3 <input type="text" name="FirstName" /> 4 <input type="text" name="LastName" /> 5 <input type="submit" value="submit" /> 6 } 7 8 @if (TempData.ContainsKey("msg")) 9 { 10 <p> 11 @TempData["msg"].ToString() 12 </p> 13 }
与之对应的还要修改HomeController中的代码:
1 namespace MvcStudy.Controllers 2 { 3 public class HomeController : Controller 4 { 5 public ActionResult Index() 6 { 7 return View(); 8 } 9 10 [HttpPost] 11 public ActionResult Index(Person person) 12 { 13 TempData["msg"] = person.FirstName + person.LastName; 14 return View(); 15 } 16 } 17 }
我们先不使用Bind注解属性,可以发现最后的输出是正确的,然后我们加上Bind注解属性:
1 [HttpPost] 2 public ActionResult Index([Bind(Prefix="p")]Person person) 3 { 4 TempData["msg"] = person.FirstName + person.LastName; 5 return View(); 6 }
重新编译,我们可以发现最后不会输出我们预想的结果了,而且还报异常了。这个时候我们考虑这个Prefix在这里起什么作用了,字面上看是前缀的意思,但是我们发现在简单类型中直接就是表示这个简单的类型将会从表单的Key为指定的值中获取。但是这里是类,所以意义就不同了,而是在类中的所有属性前加上了一个p,同时后面还追加一个点。下面我们修改Index.cshtml代码:
1 @using (Html.BeginForm()) 2 { 3 <input type="text" name="p.FirstName" /> 4 <input type="text" name="p.LastName" /> 5 <input type="submit" value="submit" /> 6 } 7 8 @if (TempData.ContainsKey("msg")) 9 { 10 <p> 11 @TempData["msg"].ToString() 12 </p> 13 }
然后我们刷新页面,重新测试,可以发现值又输出了。但是我们可以发现这个类中还有一个HomeAddress属性,但是这个属性是一个Address类,这个name怎么表示呢?你可能会认为是Address中属性的名称,但事实并不是这样的,因为而是跟上面一样通过点来分割,我们修改Index.cshtml代码如下:
1 @using (Html.BeginForm()) 2 { 3 <input type="text" name="p.FirstName" /> 4 <input type="text" name="p.LastName" /> 5 <input type="text" name="p.HomeAddress.Line1" /> 6 <input type="text" name="p.HomeAddress.Line2" /> 7 <input type="submit" value="submit" /> 8 } 9 10 @if (TempData.ContainsKey("msg")) 11 { 12 <p> 13 @TempData["msg"].ToString() 14 </p> 15 }
上面我们看到我们通过p.HomeAddress.Line1将Person的HomeAddress传递给ASP.NET MVC当然我们还要修改HomeController不然看不到最终的效果:
1 [HttpPost] 2 public ActionResult Index([Bind(Prefix="p")]Person person) 3 { 4 TempData["msg"] = person.HomeAddress.Line1 + person.HomeAddress.Line2; 5 return View(); 6 }
最后我们可以测试了,大家一定都能看到输出了吧。即便是类,也会出现数组的情况,那么我们如何呢?当然还是利用这个点来分割,只是前面不是名称而是索引值,下面我们当然还要修改Index.cshtml:
1 @using (Html.BeginForm()) 2 { 3 <input type="text" name="[0].FirstName" /> 4 <input type="text" name="[0].LastName" /> 5 <input type="text" name="[1].FirstName" /> 6 <input type="text" name="[1].LastName" /> 7 <input type="submit" value="submit" /> 8 } 9 10 @if (TempData.ContainsKey("msg")) 11 { 12 <p> 13 @TempData["msg"].ToString() 14 </p> 15 }
这里我们用的[]来作为第一个分隔符,里面的值就是索引值,下面我们还要修改HomeController,这样才能输出结果:
1 [HttpPost] 2 public ActionResult Index(List<Person> person) 3 { 4 TempData["msg"] = person.Count.ToString(); 5 return View(); 6 }
为了方便这里只输出了有多少个项,然后我们重新编译,刷新页面就可以发现输出的永远是2,无论你输入不输入值,因为http会将那四个输入框全部发送到服务端。如果你是使用js动态生成,那么麻烦就来了,就是你要负责维持这些索引,幸好ASP.NET MVC想到这点了,所以还提供了另一个解决方式,我们可以将上面的Index.cshtml改成如下代码:
1 @using (Html.BeginForm()) 2 { 3 <input type="hidden" name="index" value="first" /> 4 <input type="text" name="[first].FirstName" /> 5 <input type="text" name="[first].LastName" /> 6 <input type="hidden" name="index" value="asd" /> 7 <input type="text" name="[asd].FirstName" /> 8 <input type="text" name="[asd].LastName" /> 9 <input type="submit" value="submit" /> 10 } 11 12 @if (TempData.ContainsKey("msg")) 13 { 14 <p> 15 @TempData["msg"].ToString() 16 </p> 17 }
这里唯一的区别就是需要一个name为index的表单用来保存索引的名称,这样你只要保证索引的名称不会重复即可,但是对于动态性更强的情况来说这些还是太死板,如果可以采用字典就好了,当然我们的愿望也一样可以实现,我们只需要使用name为[索引值].key保存保存key,而利用name为[索引值].value保存值即可(value可以为类),比如我们修改Index.cshtml代码:
1 @using (Html.BeginForm()) 2 { 3 <input type="text" name="[0].key" /> 4 <input type="text" name="[0].Value" /> 5 <input type="text" name="[1].key" /> 6 <input type="text" name="[1].Value" /> 7 <input type="submit" value="submit" /> 8 } 9 10 @if (TempData.ContainsKey("msg")) 11 { 12 <p> 13 @TempData["msg"].ToString() 14 </p> 15 }
接着我们修改HomeController接收这个字典:
1 [HttpPost] 2 public ActionResult Index(Dictionary<string,string> person) 3 { 4 TempData["msg"] = string.Join(";", person.Keys); 5 return View(); 6 }
然后我们重新编译,并刷新页面,就可以看到我们输入的key提交之后都输出了
转载于:https://www.cnblogs.com/yaozhenfa/p/asp_net_mvc_model_bind_1.html
ASP.NET MVC学习之模型绑定(1)相关推荐
- ASP.NET MVC 4 (九) 模型绑定
模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: ...
- ASP.NET MVC中的模型装配 封装方法 非常好用
下面说一下 我们知道在asp.net mvc中 视图可以绑定一个实体模型 然后我们三层架构中也有一个model模型 但是这两个很多时候却是不一样的对象来的 就拿微软的官方mvc例子来说明 微软的视图实 ...
- ASP.NET MVC学习之路由篇(2)
ASP.NET MVC学习之路由篇(2) 原文:ASP.NET MVC学习之路由篇(2) 继ASP.NET MVC学习之路由篇(1)后继续学习. 7.解决与物理路径的冲突 当发送一个请求至ASP.NE ...
- ASP.NET MVC学习资料 新增几个开源项目
ASP.NET MVC学习资料 新增几个开源项目 ASP.NET MVC MSDN API: System.Web.Mvc Namespace (暂无中文版): http://msdn.micro ...
- ASP.NET MVC学习之控制器篇
一.前言 许久之后终于可以继续我的ASP.NET MVC连载了,之前我们全面的讲述了路由相关的知识,下面我们将开始控制器和动作的讲解. ASP.NET MVC学习之路由篇幅(1) ASP.NET MV ...
- (转)ASP.NET MVC 学习第一天
天道酬勤0322 博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅 | 管理 随笔:10 文章:0 评论:9 引用:0 ASP.NET MVC 学习第一天 今天开始第一天学习asp. ...
- 【ASP.NET MVC 学习笔记】- 16 Model Binding(模型绑定)
本文参考:http://www.cnblogs.com/willick/p/3424188.html. 1.Model Binding是Http请求和Action方法之间的桥梁,是MVC框架根据Htt ...
- 如何在FineUIMvc(ASP.NET MVC)视图中绑定多个模型?
起因 这是知识星球内的一个网友提出的,按理说ASP.NET MVC中一个视图只能绑定一个模型(Model),在视图顶部标识如下: @model IEnumerable<FineUICore.Ex ...
- ASP.NET MVC 学习之路-4
本文在于巩固基础 模型绑定 从URL 获取值 public ActionResult About(int id){ViewBag.Id = id;return View();} @{ViewBag.T ...
- ASP.NET MVC 4 (十) 模型验证
模型验证是在模型绑定时检查从HTTP请求接收的数据是否合规以保证数据的有效性,在收到无效数据时给出提示帮助用户纠正错误的数据. 显式模型验证 验证数据最直接的方式就是在action方法中对接收的数据验 ...
最新文章
- 差分 c语言,c语言 bmp位图差分
- 使用定制的NSDictionary的方法,对NSArray进行排序(附:数组排序两种常见方法)
- Java 14 Hotspot 虚拟机垃圾回收调优指南!
- python登录微信自动发送消息和绘画好友男女比例
- 贵州师范学院计算机2级报名,贵州省2021年上半年计算机二级报名时间
- debian执行php网页,如何在Debian上安装和使用PHP Composer
- 要让人人能AI的百度EasyDL,现在怎么样了?
- 为何python不好找工作-为什么python不好找工作
- 重磅!Apache Flink 1.11 功能前瞻来啦
- python图像边缘检测_python 简单图像处理(11) 空间域图像锐化(边缘检测)
- 数据治理的坑你遇到过几个?
- Nacos 服务注册中心
- ARCH模型以及编程实现
- Mtk平台出现NE的分析简记
- python圣诞雪人
- ECC/DH 和 ECDH
- Github复现之D-LinkNet(补全了验证部分代码,效果还行)
- PP实施经验分享(21)——(ECC版本)生产版本\BOM\工艺路线选择(涉及批量大小应用)
- Multi-Object Tracking with Multiple Cues and Switcher-Aware Classification多目标跟踪论文
- 机器人在笛卡尔空间和关节空间的多项式轨迹规划以及matlab代码(三次、五次、七次)
热门文章
- 2013 成都邀请赛
- DBCC CHECKDB 数据库或表修复
- 揭秘Mindscape WPF Elements 5新特性
- 安装卸载Windows服务
- [Material Design] MaterialButton 效果进阶 动画自动移动进行对齐效果
- Luogu1525 关押罪犯
- webpack5学习与实战-(十三)-postcss处理css3兼容性前缀
- 慕课网仿去哪儿项目笔记--(三)-城市页面制作
- ES6、7学习笔记(尚硅谷)-6-形参默认值的设置
- 如何在mysql查询结果集中得到记录行号_如何在MySQL查询结果集中得到记录行号...