现在的位置: 首页 > 综合 > 正文

Asp.Net Mvc: Model Binding to Simple Types, Co

2014年12月03日 ⁄ 综合 ⁄ 共 4729字 ⁄ 字号 评论关闭

 本文主要实验如何应用ASP.NET Mvc内建功能(DefaultModelBinder)实现简单类型、复杂类型、集合类型,以及字典类型的自动绑定。
  
  1. 简单类型
  
  这里,我们将下面这个Book类称为简单类型:
  
  public class Book
   {
   public int BookId { get; set; }
   public string BookName { get; set; }
   public string Author { get; set; }
   public DateTime PublishedDate { get; set; }
   }
  
  假设现在需要实现添加Book的功能,那么在BookController中,会定义如下的Action:
  
  [AcceptVerbs(HttpVerbs.Post)]
   public ActionResult Create(Book book) {
   //TO DO
   //Insert book into Database
   return RedirectToAction("Index");
   }
  现在的问题便是,在View中如何命名TextBox来达到自动绑定,如下:
  
  <div>
   <%using (Html.BeginForm("Create", "Book")) { %>
   <div>
   Book Name: <%=Html.TextBox("BookName")%>
   </div>
   <div>
   Author: <%=Html.TextBox("Author")%>
   </div>
   <div>
   Published Date: <%=Html.TextBox("PublishedDate")%>
   </div>
   <div>
   <input type="submit" id="submit" name="submit" value="submit" />
   </div>
   <%} %>
   </div>
  
  注意TextBox的name必须是对应绑定类型的PropertyName(不区分大小写)。 这样,页面表单submit后,我们便可以在BookController的“Create” Action中得到自动绑定的book对象。这里,ASP.NET Mvc还支持在TextBox的name中加上变量名称前缀的情形:
  
  <div>
   <%using (Html.BeginForm("Create", "Book")) { %>
   <div>
   Book Name: <%=Html.TextBox("book.BookName")%>
   </div>
   <div>
   Author: <%=Html.TextBox("book.Author")%>
   </div>
   <div>
   Published Date: <%=Html.TextBox("book.PublishedDate")%>
   </div>
   <div>
   <input type="submit" id="submit" name="submit" value="submit" />
   </div>
   <%} %>
   </div>
  
  需要注意的是:
  1)前缀"book"必须与Action中接收的Book参数名一致
  2)如果加了前缀,那么所有的都要加
  
  2. 复杂类型
  
  现在对Book类作些许改动,并引入Author类:
  
  public class Book
   {
   public int BookId { get; set; }
   public string BookName { get; set; }
   public Author Author { get; set; }
   public DateTime PublishedDate { get; set; }
   }
  
   public class Author {
   public int AuthorId { get; set; }
   public string AuthorName { get; set; }
   public string Nation { get; set; }
   }
  
  这里,将改动后的Book类称为复杂类。这时,Book类多了一个对Author类的引用。现在,保持BookController中的"Create" Action不变,来看View中的TextBox改如何命名以实现Book类型的自动绑定:
  
  <div>
   <%using (Html.BeginForm("Create", "Book")) { %>
   <div>
   Book Name: <%=Html.TextBox("BookName")%>
   </div>
   <div>
   Published Date: <%=Html.TextBox("PublishedDate")%>
   </div>
   <div>
   Author's Name: <%=Html.TextBox("Author.AuthorName")%>
   </div>
   <div>
   Author's Nation: <%=Html.TextBox("Author.Nation")%>
   </div>
   <div>
   <input type="submit" id="submit" name="submit" value="submit" />
   </div>
   <%} %>
   </div>
  
  OK,测试通过,想必你也知道命名规则了,要绑定Book类型中的Author类型,必须加上"Author."的前缀。
  如果你喜欢,你还可以在所有TextBox名称前面再加"book."的前缀。
  
  3. 集合类型
  
  为避免问题复杂化,我们用回原来的简单Book类型:
  
  public class Book
   {
   public int BookId { get; set; }
   public string BookName { get; set; }
   public string Author { get; set; }
   public DateTime PublishedDate { get; set; }
   }
  
  现在,把BookController的"Create" Action改为接收IList<Book>的参数:
  
  [AcceptVerbs(HttpVerbs.Post)]
   public ActionResult Create(IList<Book> books) {
   //TO DO
   //Insert book into Database
   return RedirectToAction("Index");
   }
  
  然后,在View中运用以下命名规则,以自动绑定IList<book>类型,
  
  <div>
   <%using (Html.BeginForm("Create", "Book")) { %>
   <div>
   Book Name: <%=Html.TextBox("books[0].BookName")%>
   </div>
   <div>
   Published Date: <%=Html.TextBox("books[0].PublishedDate")%>
   </div>
   <div>
   Author's Name: <%=Html.TextBox("books[0].Author")%>
   </div>
   <div>
   Book Name: <%=Html.TextBox("books[1].BookName")%>
   </div>
   <div>
   Published Date: <%=Html.TextBox("books[1].PublishedDate")%>
   </div>
   <div>
   Author's Name: <%=Html.TextBox("books[1].Author")%>
   </div>
   <div>
   <input type="submit" id="submit" name="submit" value="submit" />
   </div>
   <%} %>
   </div>
  
  可以看到如下规则:Action的变量名"books"加上中括号和索引作为前缀,索引必须从0开始,并且必须连续。
  通过此命名规则,可以绑定任意集合类型:IList<Book>, ICollection<Book>, IEnumerable<Book>, List<Book>, Book[]等。
  
  4. 字典类型
  
  仍以简单Book类型为例,现在将"Create" Action改为接收IDictionary<Book>类型,
  
  [AcceptVerbs(HttpVerbs.Post)]
   public ActionResult Create(IDictionary<string, Book> books) {
   //TO DO
   //Insert book into Database
   return RedirectToAction("Index");
   }
  
  相应的,View中的命名如下:
  
  <div>
   <%using (Html.BeginForm("Create", "Book")) { %>
   <div>
   Book SN: <%=Html.TextBox("books[0].Key") %>
   </div>
   <div>
   Book Name: <%=Html.TextBox("books[0].Value.BookName")%>
   </div>
   <div>
   Published Date: <%=Html.TextBox("books[0].Value.PublishedDate")%>
   </div>
   <div>
   Author's Name: <%=Html.TextBox("books[0].Value.Author")%>
   </div>
   <div>
   Book SN: <%=Html.TextBox("books[1].Key") %>
   </div>
   <div>
   Book Name: <%=Html.TextBox("books[1].Value.BookName")%>
   </div>
   <div>
   Published Date: <%=Html.TextBox("books[1].Value.PublishedDate")%>
   </div>
   <div>
   Author's Name: <%=Html.TextBox("books[1].Value.Author")%>
   </div>
   <div>
   <input type="submit" id="submit" name="submit" value="submit" />
   </div>
   <%} %>
   </div>
  
  可以看出,对于IDictioinary<Book>类型,在命名规则上,相比于集合类型,多了"Key"和"Value”的字眼。另,此规则也适用于Action参数类型为Dictionary<Book>的情形。
  
  总结:
  
  由此看来,只要我们遵循一定的命名规则,就可以轻松实现各种类型的自动绑定了。
  当然,ASP.NET Mvc还支持自定义ModelBinder扩展,请看下回分解。:-)
  
  参考文献:
  Scott Hanselman:ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries
  
  Copyright
  作者: Tristan G
  本文版权归作者和博客园共有,欢迎转载 :-)  

抱歉!评论已关闭.