ASP.NET MVC Framework体验(3):表单提交

概述

在前面的两篇文章总,我们分别做了一个简单的ASP.NET MVC的例子和进行数据的绑定,在本文中,将通过ASP.NET MVC Framework实现表单的提交,你可以看到,在这里有多种方法来获取表单数据,可以自动映射、通过Request对象获取等。

实现新增数据

1.这里我们还采用上一篇做过的Blog示例(在后面的文章中,我将一直使用该示例),在这之前,先修改一下上次示例中的BlogRepository,为其增加一个Add方法:

public void Add(Post post)
{
    BlogDataContext db = new BlogDataContext();

    db.Posts.InsertOnSubmit(post);
    db.SubmitChanges();
}

2.在Index视图中添加一个可以转向新建Post页面的链接,使用ActionLink()方法:

<h2>ASP.NET MVC Framework Sample</h2>
<hr />
<%=Html.ActionLink("Home", new { action="Index"})%> |
<%=Html.ActionLink("New Post", new { action="New"})%>

<div>
    <%foreach (Post post in ViewData)
      { %>
    <div class="postitem">
        <strong>Title</strong><%=Html.Encode(post.Title) %></br>
        <strong>Author</strong><%=Html.Encode(post.Author) %></br>
        <strong>PubDate</strong><%=Html.Encode(post.PubDate.ToShortDateString()) %></br>
        <strong>Content</strong><%=Html.Encode(post.Description) %></br>
    </div><br />
    <% } %>
</div>

在上面的代码中,第四行我们添加了New Post超链接,并指定该链接的action为New,这里我们也可以通过action名称来指定:

<h2>ASP.NET MVC Framework Sample</h2>
<hr />
<%=Html.ActionLink("Home", "Index")%> |
<%=Html.ActionLink("New Post", "New")%>

<div>
    <%foreach (Post post in ViewData)
      { %>
    <div class="postitem">
        <strong>Title</strong><%=Html.Encode(post.Title) %></br>
        <strong>Author</strong><%=Html.Encode(post.Author) %></br>
        <strong>PubDate</strong><%=Html.Encode(post.PubDate.ToShortDateString()) %></br>
        <strong>Content</strong><%=Html.Encode(post.Description) %></br>
    </div><br />
    <% } %>
</div>

3.编写控制器中的New action代码,这里代码非常简单,因为我们只需要转向新建Post视图就可以了,并不需要其他的操作:

[ControllerAction]
public void New()
{ 
    //转向新页面
    RenderView("New");
}

4.编写New视图,在这里我们将提供一些表单,供用户输入数据,编写HTML代码如下:

<h2>New Post</h2>
<hr />
<div class="postitem">
    Title:<input id="title" name="title" type="text" /><br /><br />
    Author:<input id="author" name="author" type="text" /><br /><br />
    Content:<textarea id="description" name="description" cols="40" rows="5"></textarea><br /><br />
    <input type="submit" value="Save" />
</div>
接下来添加一个HTML的form元素,并指定它的action为我们要增加新的Post的action,这里假定为Add,并且指定method为Post,最终我们完成的代码应该看起来如下所示:
<h2>New Post</h2>
<hr />
<div class="postitem">
    <form action="Add" method="post">
        Title:<input id="title" name="title" type="text" /><br /><br />
        Author:<input id="author" name="author" type="text" /><br /><br />
        Content:<textarea id="description" name="description" cols="40" rows="5"></textarea><br /><br />
        <input type="submit" value="Save" />
    </form>
</div>

获取表单数据

完成了上面的步骤之后,就可以编写控制器中Add action的代码,在这里需要获取表单的数据,并将其写入到数据库,ASP.NET MVC Framework中提供了多种方法获取表单数据。

1.自动映射

使用这种方法,我们只需要把方法的参数定义表单的名称,ASP.NET MVC Framework将会自动帮助我们进行映射,直接把表单的数据赋值给form的Action所对应的方法参数上,如下代码所示:

[ControllerAction]
public void Add(string title, string author, string description)
{
    Post post = new Post();
    post.Title = title;
    post.Author = author;
    post.Description = description;
    post.PubDate = DateTime.Now;

    BlogRepository repository = new BlogRepository();
    repository.Add(post);

    RedirectToAction("Index");
}

2.第一种方法在使用时,如果界面上表单过多,会使方法的参数变大,这样好像就变成了重构中所说的“脏代码”,为了解决这个问题,我们还可以使用窗体变量来获取表单的值,使其代码看起来如下所示:

[ControllerAction]
public void Add()
{
    Post post = new Post();
    post.Title = Request.Form["title"];
    post.Author = Request.Form["author"];
    post.Description = Request.Form["description"];
    post.PubDate = DateTime.Now;

    BlogRepository repository = new BlogRepository();
    repository.Add(post);

    RedirectToAction("Index");
}

上面这两种方法都是获取表单的值,并将其保存到数据库中,转向Index action进行处理。

3. 在MVCToolkit中还提供了一些扩展的方法,可以用来获取表单的值,后面的文章再说。

配置路径选择

这一步什么时候都不能忘,这次我们修改一下,变为controller/action的形式,代码如下:

void Application_Start(object sender, EventArgs e) 
{
    // Code that runs on application startup
    RouteTable.Routes.Add(
                new Route
                {
                    Url = "[controller]/[action]",
                    Defaults = new { action = "Index" },
                    RouteHandler = typeof(MvcRouteHandler)
                });
}

完成数据增加

上面的示例运行后如下所示,首先是Index视图中有一个New Post链接:

 TerryLee_MVC_007

点击New Post后:

 TerryLee_MVC_008

提交之后,增加一条新的Post,并转向Index视图:

TerryLee_MVC_009 

结束语

关于在ASP.NET MVC Framework中实现表单的提交简单示例到这里就结束,相信通过前面三篇简单的文章,大家对ASP.NET MVC Framework已经有了一个大概的认识,后面我会写一些深入一点的文章以及MVCToolkti提供的一些HTML Helper方法:)

示例代码下载:/Files/Terrylee/MVCDemo03.rar
作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2007-12-12 23:08 TerryLee 阅读(8187) 评论(45)  编辑 收藏 网摘 所属分类: [08]  Web开发

  回复  引用  查看    
#1楼 2007-12-13 00:23 | 魔幻天空      
这么晚发帖!楼主好强大!!好文,赞一个!!
  回复  引用  查看    
#2楼 [楼主]2007-12-13 00:25 | TerryLee      
@魔幻天空
呵呵,最近睡的比较晚:)
  回复  引用  查看    
#3楼 2007-12-13 01:00 | 魔佛之间      
哈哈...前面还有一个魔,魔王都是晚上出动么?
不过,博主的贴子很好,很强大!

连接下载请使用绝对地址:
http://terrylee.cnblogs.com/Files/Terrylee/MVCDemo03.rar

有一个问题,不知道会军兄做过这个练习没:http://blog.joycode.com/scottgu/archive/2007/11/14/111385.aspx

但我的总是提示在ProductsController里没有定义Action:"Index",我的Routing也是和他的教程里一样,后来复制一个Action:Categories()作为"Index",才运行下去,我想问题在才是在RouteTable里,便仔细检查了URL Routing,也没看出哪里不对,不知RTM和Scott写教材的版本有什么不同才会导致这样.

希望会军兄详细解释下Mvc的Routing(路径选择)

  回复  引用    
#4楼 2007-12-13 05:39 | [心有灵犀] [未注册用户]
继续学习
  回复  引用    
#5楼 2007-12-13 08:04 | johnnytbz [未注册用户]
关注
  回复  引用  查看    
#6楼 2007-12-13 08:40 | 猪怕壮      
完全照搬castle,微软没人品
  回复  引用  查看    
#7楼 2007-12-13 08:47 | lovecherry      
@猪怕壮
微软喜欢在各个方面都全面发展,看到好的思想及时吸收,并且提供官方的方案,对开发者来说不一定是坏事情,大家都喜欢官方这个有保障的词语
  回复  引用  查看    
#8楼 2007-12-13 08:53 | 飞仙      
学习
  回复  引用  查看    
#9楼 2007-12-13 09:11 | kasafuma      
«»
  回复  引用  查看    
#10楼 2007-12-13 11:07 | 戏水      
建议楼主和 天哥一样 录制视频 配音讲解
  回复  引用  查看    
#11楼 2007-12-13 11:24 | Awen      
这个拓展框架只可以用于3.5版本的,目前2.0的还是用monorail比较方便吧!
;)
  回复  引用    
#12楼 2007-12-13 11:33 | 山清水秀风景 [未注册用户]
学习中
  回复  引用    
#13楼 2007-12-13 11:40 | holygrace [未注册用户]
我有个问题,mvc是通过url映射到控制器的类上的,比如/products/add会映射添加产品的方法,但如果我一个页面需要调用很多不同的类,不同的方法怎么映射?比如首页!
  回复  引用  查看    
#14楼 [楼主]2007-12-13 12:31 | TerryLee      
@魔佛之间
魔王都是晚上出动,呵呵,这个例子我没做过

等下篇文章吧,写一下路径选择:)
  回复  引用  查看    
#15楼 [楼主]2007-12-13 12:32 | TerryLee      
@[心有灵犀]
:)
  回复  引用  查看    
#16楼 [楼主]2007-12-13 12:32 | TerryLee      
@飞仙
:)
  回复  引用  查看    
#17楼 [楼主]2007-12-13 12:32 | TerryLee      
@kasafuma
《》?
  回复  引用  查看    
#18楼 [楼主]2007-12-13 12:33 | TerryLee      
@戏水
录视频恐怕没有那么多的时间,毕竟我还要上班,还有很多事情要做,只能利用业务时间写一点文章
  回复  引用  查看    
#19楼 [楼主]2007-12-13 12:33 | TerryLee      
@Awen

  回复  引用  查看    
#20楼 [楼主]2007-12-13 12:33 | TerryLee      
@山清水秀风景
:)
  回复  引用  查看    
#21楼 [楼主]2007-12-13 12:38 | TerryLee      
@holygrace
首页的映射,比如说如下:
Product/Index,它对应的就是Index action,首页的处理都会在Index这个action里面做
不太明白您的意思,能否再说明白一点呢?
  回复  引用  查看    
#22楼 [楼主]2007-12-13 12:45 | TerryLee      
@猪怕壮
借鉴对于开发者来说未必就是坏事啊,就像lovecherry 说的,吸收好的思想,提供官方的方案,有什么错呢?
  回复  引用  查看    
#23楼 2007-12-13 12:54 | 李永京      
在MVC中权限问题怎么弄呢?比如登录,按权限分配相应的操作,进入相应页面.....
  回复  引用  查看    
#24楼 2007-12-13 12:58 | 坐断东南 笑煞之!!      
又来晚了。。
唉。。

留下标记。。 学学。。
:)
  回复  引用  查看    
#25楼 [楼主]2007-12-13 13:20 | TerryLee      
@李永京
这跟权限问题没什么关系吧?
  回复  引用  查看    
#26楼 [楼主]2007-12-13 13:20 | TerryLee      
@坐断东南 笑煞之!!
:)
  回复  引用  查看    
#27楼 2007-12-13 13:34 | ringwang      
学习
  回复  引用  查看    
#28楼 2007-12-13 13:37 | 李永京      
@TerryLee
是这样的,如何在MVC框架中处理在原来的权限问题?比如在一般情况下,利用登录页根据id,保存session,权限跳到相应页面,进行操作(修改、删除)。这些在MVC框架中不知道怎么编码实现了?这与这篇文章确实没有关系,呵呵。
  回复  引用  查看    
#29楼 [楼主]2007-12-13 13:50 | TerryLee      
@ringwang
:)
  回复  引用  查看    
#30楼 [楼主]2007-12-13 13:50 | TerryLee      
@李永京
现在同样可以做啊,可以在controller中根据权限,呈现不同的view就行了
  回复  引用  查看    
#31楼 2007-12-13 13:54 | 李永京      
@TerryLee
谢谢指教!!呵呵
  回复  引用  查看    
#32楼 2007-12-13 14:54 | superstar      
MVC不懂,以前只在JAVA搞过
  回复  引用    
#33楼 2007-12-13 15:19 | longer [未注册用户]
居然楼上的放广告
  回复  引用    
#34楼 2007-12-13 15:24 | Mic [未注册用户]
快写MVCToolkit的用法吧。还有Web控件好像不能用了智能感知没了 一编译还说不存在,咋回事?
  回复  引用  查看    
#35楼 [楼主]2007-12-13 16:56 | TerryLee      
@superstar
看一下就行了:)
  回复  引用  查看    
#36楼 [楼主]2007-12-13 16:56 | TerryLee      
@longer
已经被删除
  回复  引用  查看    
#37楼 [楼主]2007-12-13 16:58 | TerryLee      
@Mic
嗯,慢慢来,尽量写快一点

智能感知现在有些问题,参考第二篇中的回复
  回复  引用    
#38楼 2007-12-14 09:54 | Mic [未注册用户]
@TerryLee
智能感知及代码后置编译不能通过的退一步完美方案。直接将脚本写在页面上吧这样就又找能智能的感觉了,编译也不报错了。
看来MVC还会继续完善的,要不就成MVC之V爱上了C,哈哈哈

  回复  引用  查看    
#39楼 [楼主]2007-12-14 10:42 | TerryLee      
@Mic
呵呵,先这样解决,也许下一步就会解决这个问题了:)
  回复  引用  查看    
#40楼 2007-12-14 10:56 | 啊东      
代码越写越少咯,继续学习~

  回复  引用  查看    
#41楼 2007-12-17 13:32 | Ryan Yu      
@Terry Lee
学习了,感谢你的辛勤付出~
  回复  引用  查看    
#42楼 [楼主]2007-12-17 18:57 | TerryLee      
@Ryan Yu
客气了 :)
  回复  引用    
#43楼 2008-03-24 14:57 | ling.ling [未注册用户]
强,不过我现在也在学习mvc啊
  回复  引用  查看    
#44楼 [楼主]2008-03-24 21:19 | TerryLee      
@ling.ling
过奖了:)
  回复  引用  查看    
#45楼 2008-05-14 21:55 | 镜涛      
学习啦

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-10-28 12:49 编辑过
Google站内搜索




相关链接:

历史上的今天:
2005-12-12 利用委托机制处理.NET中的异常