随笔 - 7  文章 - 0  评论 - 87  阅读 - 31696 

环境:

Windows 2008, VS 2008 SP1, Asp.Net Mvc 1.0

------------------------------------------------------------------------------

本文主要实验如何应用Asp.Net Mvc内建功能(DefaultModelBinder)实现简单类型、复杂类型、集合类型,以及字典类型的自动绑定。

1. 简单类型

这里,我们将下面这个Book类称为简单类型:

复制代码
public class Book
    {
        
public int BookId { getset; }
        
public string BookName { getset; }
        
public string Author { getset; }
        
public DateTime PublishedDate { getset; }
    }
复制代码


假设现在需要实现添加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 { getset; }
        
public string BookName { getset; }
        
public Author Author { getset; }
        
public DateTime PublishedDate { getset; }
    }

    
public class Author {
        
public int AuthorId { getset; }
        
public string AuthorName { getset; }
        
public string Nation { getset; }
    }
复制代码


这里,将改动后的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 { getset; }
        
public string BookName { getset; }
        
public string Author { getset; }
        
public DateTime PublishedDate { getset; }
    }
复制代码


现在,把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

posted on   Tristan G  阅读(2712)  评论(5编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示