一.前言

下面我们将开始学习模型绑定,通过下面的知识我们将能够理解ASP.NET MVC模型的模型绑定器是如何将http请求中的数据转换成模型的,其中我们重点讲述的是表单数据。

二.正文

1.简单类型绑定

学过一定ASP.NET MVC都会为这个特点所骄傲,就是能够将表单中与同名的参数映射,这相比操作ASP.NET控件来获取值轻便了许多,但是正如上面所说的那样要同名(大小写不区分),下面我们会讲述如何自己去指定。

首先我们在HomeController如果不存在则创建)中获取表单中的值并显示:

 namespace MvcStudy.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
} [HttpPost]
public ActionResult Index(String person)
{
TempData["msg"] = person ?? "";
return View();
}
}
}

接着我们在Views/Home/Index.cshtml中写入如下代码:

 @{
ViewBag.Title = "Index";
} @using (Html.BeginForm())
{
<input type="text" name="perSon" />
<input type="submit" value="submit" />
} @if (TempData.ContainsKey("msg"))
{
<p>
@TempData["msg"].ToString()
</p>
}

这里我们有一个nameperSon的输入框,下面我们在提交后还输出了这个值。下面读者可以尝试输入一个值,可以看到下面会对应的输出。但是这个时候我们将nameperSon的输入框改成persons就不会显示了。理由很简单,因为名称不同了,但是通过Bind注解属性可以解决这个问题,下面我们打开HomeController并修改代码:

 [HttpPost]
public ActionResult Index([Bind(Prefix="persons")]String person)
{
TempData["msg"] = person ?? "";
return View();
}

这里我们通过BindPrefix修改了person的前缀,然后重新编译,我们可以发现又显示了。这样以后我们并不需要名称都一样了。

上面介绍的只是对于一个简单类型的情况,当然多的可以以此类推,但如果是数组呢?得益于ASP.NET MVC的默认模型绑定我们只要重复同一个name多次,就可以简单的形成了数组了比如我们将Index.cshtml改成如下代码:

 @using (Html.BeginForm())
{
<input type="text" name="persons" />
<input type="text" name="persons" />
<input type="text" name="persons" />
<input type="text" name="persons" />
<input type="text" name="persons" />
<input type="text" name="persons" />
<input type="submit" value="submit" />
} @if (TempData.ContainsKey("msg"))
{
<p>
@TempData["msg"].ToString()
</p>
}

作为演示我们只是简单的将输入框复制了几遍,下面我们修改HomeController的代码:

 [HttpPost]
public ActionResult Index([Bind(Prefix="persons")]IList<String> person)
{
TempData["msg"] = String.Join(";", person);
return View();
}

通过上面代码我们可以看到即使是数组一样也是可以使用Bind注解属性的,同时类型也改成了IList<String>,下面我们通过StringJoin方法将这个数组拼接成一个数组,中间以分号分割。读者这个时候可以重新编译然后尝试,最后的效果如下所示:

2.复合类型绑定

很多实际的情况我们都会使用一个复合类型取代多个简单类型,那么问题就来了,ASP.NET MVC是如何绑定呢?对于一个复合类型,还是会按照名称映射到复合属性中对应的属性,但是好奇的人一定会使用Bind注解属性,想看看会发生什么事情,那么我们下面就 模拟一下,首先我们新建一个简单的Person类:

 namespace MvcStudy.Models
{
public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
public Address HomeAddress { get; set; }
}
}

还有一个Address类(后面需要使用):

 namespace MvcStudy.Models
{
public class Address
{
public String Line1 { get; set; }
public String Line2 { get; set; }
}
}

接着我们修改Index.cshtml将其中的表单的输入框于Person对应起来:

 @using (Html.BeginForm())
{
<input type="text" name="FirstName" />
<input type="text" name="LastName" />
<input type="submit" value="submit" />
} @if (TempData.ContainsKey("msg"))
{
<p>
@TempData["msg"].ToString()
</p>
}

与之对应的还要修改HomeController中的代码:

 namespace MvcStudy.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
} [HttpPost]
public ActionResult Index(Person person)
{
TempData["msg"] = person.FirstName + person.LastName;
return View();
}
}
}

我们先不使用Bind注解属性,可以发现最后的输出是正确的,然后我们加上Bind注解属性:

 [HttpPost]
public ActionResult Index([Bind(Prefix="p")]Person person)
{
TempData["msg"] = person.FirstName + person.LastName;
return View();
}

重新编译,我们可以发现最后不会输出我们预想的结果了,而且还报异常了。这个时候我们考虑这个Prefix在这里起什么作用了,字面上看是前缀的意思,但是我们发现在简单类型中直接就是表示这个简单的类型将会从表单的Key为指定的值中获取。但是这里是类,所以意义就不同了,而是在类中的所有属性前加上了一个p,同时后面还追加一个点。下面我们修改Index.cshtml代码:

 @using (Html.BeginForm())
{
<input type="text" name="p.FirstName" />
<input type="text" name="p.LastName" />
<input type="submit" value="submit" />
} @if (TempData.ContainsKey("msg"))
{
<p>
@TempData["msg"].ToString()
</p>
}

然后我们刷新页面,重新测试,可以发现值又输出了。但是我们可以发现这个类中还有一个HomeAddress属性,但是这个属性是一个Address类,这个name怎么表示呢?你可能会认为是Address中属性的名称,但事实并不是这样的,因为而是跟上面一样通过点来分割,我们修改Index.cshtml代码如下:

 @using (Html.BeginForm())
{
<input type="text" name="p.FirstName" />
<input type="text" name="p.LastName" />
<input type="text" name="p.HomeAddress.Line1" />
<input type="text" name="p.HomeAddress.Line2" />
<input type="submit" value="submit" />
} @if (TempData.ContainsKey("msg"))
{
<p>
@TempData["msg"].ToString()
</p>
}

上面我们看到我们通过p.HomeAddress.Line1PersonHomeAddress传递给ASP.NET MVC当然我们还要修改HomeController不然看不到最终的效果:

 [HttpPost]
public ActionResult Index([Bind(Prefix="p")]Person person)
{
TempData["msg"] = person.HomeAddress.Line1 + person.HomeAddress.Line2;
return View();
}

最后我们可以测试了,大家一定都能看到输出了吧。即便是类,也会出现数组的情况,那么我们如何呢?当然还是利用这个点来分割,只是前面不是名称而是索引值,下面我们当然还要修改Index.cshtml

 @using (Html.BeginForm())
{
<input type="text" name="[0].FirstName" />
<input type="text" name="[0].LastName" />
<input type="text" name="[1].FirstName" />
<input type="text" name="[1].LastName" />
<input type="submit" value="submit" />
} @if (TempData.ContainsKey("msg"))
{
<p>
@TempData["msg"].ToString()
</p>
}

这里我们用的[]来作为第一个分隔符,里面的值就是索引值,下面我们还要修改HomeController,这样才能输出结果:

 [HttpPost]
public ActionResult Index(List<Person> person)
{
TempData["msg"] = person.Count.ToString();
return View();
}

为了方便这里只输出了有多少个项,然后我们重新编译,刷新页面就可以发现输出的永远是2,无论你输入不输入值,因为http会将那四个输入框全部发送到服务端。如果你是使用js动态生成,那么麻烦就来了,就是你要负责维持这些索引,幸好ASP.NET MVC想到这点了,所以还提供了另一个解决方式,我们可以将上面的Index.cshtml改成如下代码:

 @using (Html.BeginForm())
{
<input type="hidden" name="index" value="first" />
<input type="text" name="[first].FirstName" />
<input type="text" name="[first].LastName" />
<input type="hidden" name="index" value="asd" />
<input type="text" name="[asd].FirstName" />
<input type="text" name="[asd].LastName" />
<input type="submit" value="submit" />
} @if (TempData.ContainsKey("msg"))
{
<p>
@TempData["msg"].ToString()
</p>
}

这里唯一的区别就是需要一个nameindex的表单用来保存索引的名称,这样你只要保证索引的名称不会重复即可,但是对于动态性更强的情况来说这些还是太死板,如果可以采用字典就好了,当然我们的愿望也一样可以实现,我们只需要使用name[索引值].key保存保存key,而利用name[索引值].value保存值即可(value可以为类),比如我们修改Index.cshtml代码:

 @using (Html.BeginForm())
{
<input type="text" name="[0].key" />
<input type="text" name="[0].Value" />
<input type="text" name="[1].key" />
<input type="text" name="[1].Value" />
<input type="submit" value="submit" />
} @if (TempData.ContainsKey("msg"))
{
<p>
@TempData["msg"].ToString()
</p>
}

接着我们修改HomeController接收这个字典:

 [HttpPost]
public ActionResult Index(Dictionary<string,string> person)
{
TempData["msg"] = string.Join(";", person.Keys);
return View();
}

然后我们重新编译,并刷新页面,就可以看到我们输入的key提交之后都输出了

ASP.NET MVC学习之模型绑定(1)的更多相关文章

  1. ASP.NET MVC学习之模型绑定(2)

    3.手工调用模型绑定 很多情况下我们都是通过形参的方式接收来自http流中的数据,这看似是完美的,但是缺少了很多过程中的控制,所以我们就需要使用手工的方式进行绑定.下面我们通过一个例子来说明,首先打开 ...

  2. .NET MVC学习之模型绑定

    ASP.NET MVC学习之模型绑定(2)   继ASP.NET MVC学习之模型绑定继续 3.手工调用模型绑定 很多情况下我们都是通过形参的方式接收来自http流中的数据,这看似是完美的,但是缺少了 ...

  3. ASP.NET MVC学习之模型验证详解

    ASP.NET MVC学习之模型验证篇 2014-05-28 11:36 by y-z-f, 6722 阅读, 13 评论, 收藏, 编辑 一.学习前的一句话 在这里要先感谢那些能够点开我随笔的博友们 ...

  4. Asp.net Mvc 中的模型绑定

    asp.net mvc中的模型绑定可以在提交http请求的时候,进行数据的映射. 1.没有模型绑定的时候 public ActionResult Example0() { ) { string id ...

  5. [转]ASP.NET MVC 4 (九) 模型绑定

    本文转自:http://www.cnblogs.com/duanshuiliu/p/3706701.html 模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C ...

  6. ASP.NET MVC 4 (九) 模型绑定

    模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: ...

  7. ASP.NET MVC学习之模型验证篇

    一.学习前的一句话 在这里要先感谢那些能够点开我随笔的博友们.慢慢的已经在博客园中度过一年半了,伊始只是将博客园作为自己学习的记录本一样使用,也不敢将自己的随笔发表到博客园首页,生怕自己的技艺不高,反 ...

  8. ASP.NET MVC学习之模型模板篇

    一.前言 如果你使用ASP.NET MVC制作后台一定会爱上它的EditorForModal.DisplayForModal和LabelForModal方法,因为这些方法可以将模型直接变成对应的标签, ...

  9. ASP.NET MVC中的模型绑定

    模型绑定的本质   任何控制器方法的执行都受action invoker组件(下文用invoker代替)控制.对于每个Action方法的参数,这个invoker组件都会获取一个Model Binder ...

随机推荐

  1. 【转】用Python实现各种排序算法

    以下代码均为python3版本的代码 # 冒泡排序 # 比较相邻的元素大小,将小的前移,大的后移,就像水中的气泡一样,最小的元素经过几次移动,会最终浮到水面上. def bubbleSort(list ...

  2. 多台web如何共享session进行存储(转载)

    session的存储了解以前是怎么做的,搞清楚了来龙去脉,才会明白进行共享背后的思想和出发点.我喜欢按照这样的方式来问(或者去搞清楚):为什么要session要进行共享,不共享会什么问题呢? php中 ...

  3. ubuntu14.04下配置使用openCV3.0

    [操  作  系  统] Ubuntu 14.04 LTS [OpenCV版本]  3.0.0-beta [Eclipse 版 本] 3.8.1 需要知识: Linux系统shell命令基础 编译原理 ...

  4. Java第一天学习笔记整理

    一.关键字 java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名.方法名.类名.包名. 常见的关键字: 用于定义数据类型的关键字 cla ...

  5. python 排序

    python 写的排序,实现起来还是比较简单 #快速排序 def qsort(L): if len(L)>1: return qsort([i for i in L[1:] if i<L[ ...

  6. jquery table 拼接集合

    1html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <ti ...

  7. JS中的this对象详解

    JS中this关键字很常见,但是它似乎变幻莫测,让人抓狂.这篇文章就来揭示其中的奥秘. 借助阮一峰老师的话:它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.这句话看似平常,可是要非常注意 ...

  8. Windows XP SP3下编译安装openssl-1.1.0b

    软件需要: openssl-1.1.0b visual studio 2010(cn_visual_studio_2010_ultimate_x86_dvd_532347.iso) perl:Acti ...

  9. Lua.LearningLua.5-document-for-luaL_findtable-function

    Learning Lua: 5 - Document for luaL_findtable() function 文档中没有找到luaL_findtable()函数的说明,这里尝试补充. LUALIB ...

  10. Spring 4 官方文档学习(十一)Web MVC 框架之约定优于配置

    当返回一个ModelAndView时,可以使用其addObject(Object obj)方法,此时的约定是: An x.y.User instance added will have the nam ...