ASP.NET MVC案例教程(四)

前言

通过前几篇文章,我们已经能比较自如的使用ASP.NET MVC来呈现页面和数据了。但是,有一个大问题没有解决:如何处理表单数据。例如,我们将要实现的公告发布功能,用户肯定是在某个表单页面输入标题、正文等内容,而后提交,然后表单数据要被传递到相应的地方交由业务逻辑组件处理。

在传统的ASP.NET下,使用的是Model1模式,每个aspx页面有一个同名的aspx.cs文件,当提交表单时,默认数据被提交到这个同名aspx.cs文件中某个方法下处理。但是,在ASP.NET MVC中,这种方法不能用了,因为我们换用了Model2模式,不能再用同名代码文件来处理aspx的提交请求(但是这不表明同名代码文件就没有用了,实际上,它依然会被执行,但是我们不提倡在里面处理任何逻辑,但是,有时会利用它进行一些初始化操作。),那么应该怎么做呢?不多讲,我们以例子说明问题。

下面我们一步一步完成“MVC公告发布系统”的公告发布功能,等做完这个功能,上面的问题就明了了。

建立输入信息页面

下面,正式开始我们的工作。首先,我要建立一个页面,用来让用户输入公告信息。而我们知道,在ASP.NET MVC中不能直接请求aspx文件,任何请求都要通过Controller,所以,我们首先在Controllers目录下建立一个新的Controller类,名叫AnnounceController。删除其中自动生成的Index方法,新建一个名叫Release的Action方法,具体代码如下。

AnnounceController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MVCDemo.Models;
using MVCDemo.Models.Interfaces;
using MVCDemo.Models.Entities;
namespace MVCDemo.Controllers
{
public class AnnounceController : Controller
{
public ActionResult Release()
{
ICategoryService cServ = ServiceBuilder.BuildCategoryService();
List categories = cServ.GetAll();
ViewData["Categories"] = new SelectList(categories, "ID",
"Name");
return View("Release");
}
}
}

这个就是要呈现表单页的Action方法,看看它做了什么:它首先取出所有的分类,然后将它们转成SelectList类型存入ViewData,最后呈现Release视图。

为什么要取出所有分类呢?因为我们在发布公告时希望有个下拉列表框列出所有公告名称,让用户可以选择要发布的公告属于哪个分类。而SelectList是ASP.NET MVC中用于绑定到下拉列表的类型。它有很多重载的构造方法,其中我使用的是三个参数的,它们分别表示:生成数据的枚举,绑定到value的字段名,绑定到列表名称的字段名。这里,将把所有分类实体集合绑定到下拉列表,而ID属性作为值,Name属性作为显示在列表框中的名字。

如果我们不需要下拉列表框来显示所有分类,那么Release方法只需一行return View("Release");就可以了。

Action方法做完了,我们还需要视图。在Views目录下建立Announce目录,再在这个Announce目录下建立Release.aspx视图。代码如下。

Release.aspx:

<%@ Page Language="C#"
AutoEventWireup="true" CodeBehind="Release.aspx.cs"
Inherits="MVCDemo.Views.Announce.Release" %>

<%@ Import Namespace="MVCDemo.Models.Entities" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">
<title>

</title>

</head>

<body>

<% SelectList categories =
ViewData["Categories"] as SelectList; %>

<div>

<h1>

MVC公告发布系统——发布公告</h1>

<% Html.BeginForm("DoRelease","Announce",FormMethod.Post);
%>

<dl>

<dt>

标题:</dt>

<dd>

<%= Html.TextBox("Title") %>

</dd>

<dt>

分类:</dt>

<dd>

<%= Html.DropDownList("Category",categories) %>

</dd>

<dt>

内容:</dt>

<dd>

<%= Html.TextArea("Content") %>

</dd>

</dl>

<input type="submit"
value="发布" />

<% Html.EndForm(); %>

</div>

</body>

</html>

代码不复杂,但是要注意几个地方。categories不多说了,这是刚才我们传递过来的所有分类组成的列表项。我觉得大家迷惑的可能是那些Html.***的东西,其实,Html是ViewPage的中的一个对象(ViewPage是所有视图的基类),它主要的左右就是产生各种表单项(先这么认为吧,其实它还有其他功能),例如Html.BeginForm就是说这里开始一个form标签,而Html.EndForm当然是form标签结束。其他几个,看名字相信大家也猜出来了。

至于为什么这么做,也不直接使用原始的HTML标签,我先不多说,以后大家做多了自然就理解了,目前大家只要知道,这样做可以避免一个url问题以及让url更灵活就行了。

回到这个页面,BeginForm有三个参数,分别是提交请求的Action名,提交请求的Controller名和请求方式。所以,这个页面的意思就是使用post方法请求http://localhost/Announce/DoRelease这个Action来处理我们的请求。

页面中有三个输入表单和一个提交按钮。三个输入表单分别是:名叫Title的文本框,名叫Content的文本域和名叫Category的下拉列表框。注意下拉列表是怎么绑定的,只要将含有数据的SelectList作为第二个参数就行了。完成后,页面是这样子的:

处理请求

现在我们可以输入信息了,但是如果你输入后点提交,你会发现产生了经典的404错误。刚才我们说了,表单提交到的Action是Announce下的DoRelease,但是现在没有这个Action,当然会404了。下面,我们来建立这个处理程序。

回到AnnounceController,新建Action方法DoRelease,具体代码如下。

AnnounceController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MVCDemo.Models;
using MVCDemo.Models.Interfaces;
using MVCDemo.Models.Entities;
namespace MVCDemo.Controllers
{
public class AnnounceController : Controller
{
public ActionResult Release()
{
ICategoryService cServ = ServiceBuilder.BuildCategoryService();
List categories = cServ.GetAll();
ViewData["Categories"] = new SelectList(categories, "ID",
"Name");
return View("Release");
}
public ActionResult DoRelease()
{
AnnounceInfo announce = new AnnounceInfo()
{
ID = 1,
Title = Request.Form["Title"],
Category = Int32.Parse(Request.Form["Category"]),
Content = Request.Form["Content"],
};
IAnnounceService aServ = ServiceBuilder.BuildAnnounceService();
aServ.Release(announce);
ViewData["Announce"] = announce;
return View("ReleaseSucceed");
}
}
}

我们看,它首先新建一个AnnounceInfo类型的实体类,用来存贮这个新的公告的信息。注意它是怎么得到表单信息的,对了,用了Request.Form["表单名"],这就是获得表单信息的一种方法,当然还有其他方法,但是我推荐这一种。注意,这里的表单名就是我们使用Html.***方法生成表单时的名字。

OK,下面就是调用业务逻辑组件,完成发布公告功能。

但是这里有个问题,我们的业务逻辑组件是Mock的,也就是说其实什么都没做啊。如果是真的业务逻辑组件,我们可以去数据库看看有没有添加公告信息成功,可是这里没有,我们要怎么证明表单数据传递过来了呢?于是我想了一个办法,有新加了一个ReleaseSucceed视图,用来显示新发布公告的信息,以此证明我们确实把表单信息传过来了。ReleaseSucceed视图如下:

ReleaseSucceed.aspx:

<%@ Page Language="C#"
AutoEventWireup="true" CodeBehind="ReleaseSucceed.aspx.cs"
Inherits="MVCDemo.Views.Announce.ReleaseSucceed" %>

<%@ Import Namespace="MVCDemo.Models.Entities" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title></title>

</head>

<body>

<% AnnounceInfo announce =
ViewData["Announce"] as AnnounceInfo; %>

<div>

<h1>MVC公告发布系统——发布公告成功</h1>

<dl>

<dt>ID:</dt>

<dd><%= announce.ID %></dd>

<dt>标题:</dt>

<dd><%= announce.Title %></dd>

<dt>类别ID:</dt>

<dd><%= announce.Category %></dd>

<dt>内容:</dt>

<dd><%= announce.Content %></dd>

</dl>

</div>

</body>

</html>

这些代码就不用我过多解释了。下面,我们输入一些信息,提交看看:

看到没有,我没有骗你们,表单数据真的传过来了!

小结

通过这四篇文章,我们已经了解了ASP.NET MVC的基本原理,并且已经会呈现数据页面及传递表单数据处理了。会了这些,其实已经可以应付绝大多数主要开发了。从下篇开始,我们接触一些高级点的内容。下篇将说一下ASP.NET MVC如何与ASP.NET AJAX及JQuery结合,再后面,会讲到拦截器及与Silverlight结合的内容。

ASP.NET MVC案例教程(四)的更多相关文章

  1. ASP.NET MVC案例教程(五)

    ASP.NET MVC案例教程(四) 前言 通过前几篇文章,我们已经能比较自如的使用ASP.NET MVC来呈现页面和数据了.但是,有一个大问题没有解决:如何处理表单数据.例如,我们将要实现的公告发布 ...

  2. ASP.NET MVC案例教程(二)

    ASP.NET MVC案例教程(二) 让第一个页面跑起来 现在,我们来实现公告系统中的第一个页面——首页.它非常简单,只包括所有公告分类的列表,并且每个列表项是一个超链接.其中分类数据是用我们的Moc ...

  3. ASP.NET MVC案例教程(三)

    ASP.NET MVC案例教程(二) 让第一个页面跑起来 现在,我们来实现公告系统中的第一个页面——首页.它非常简单,只包括所有公告分类的列表,并且每个列表项是一个超链接.其中分类数据是用我们的Moc ...

  4. ASP.NET MVC案例教程(一) 准备

    ASP.NET MVC案例教程(一) 前言 ASP.NET MVC作为微软官方的MVC解决方案,推出有一段时间了.可以说自动推出以来,一直广受关注.在经历了漫长的Preview之后,前几天终于推出了其 ...

  5. ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第四篇:传递表单数据

    摘要      本文将完成我们“MVC公告发布系统”的公告发布功能,以此展示在ASP.NET MVC中如何传递处理表单的数据. 前言      通过前几篇文章,我们已经能比较自如的使用ASP.NET ...

  6. ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第一篇:准备工作

    摘要      本文将简要介绍这个文章系列的目的.形式及大体内容.并且完成开始学习这个系列前所必要的准备工作. 前言      ASP.NET MVC作为微软官方的MVC解决方案,推出有一段时间了.可 ...

  7. ASP.NET MVC案例教程(七)

      前言 写这篇文章的目的,是想总结一些东西,以帮助朋友们更好的使用这个框架.但是,我又不像把官方列举的哪些优势.功能翻译过来列举在这里.所以,我想干脆我就纯从个人观点上对这个框架评论一下吧.说的不好 ...

  8. ASP.NET MVC案例教程(六)

    ASP.NET六 一个小难题 我们继续完善“MVC公告发布系统”,这次,我们的需求是对公告发布功能添加日志记录能力,即在发布公告前,记录一次,在公告发布成功后,再记录一次.然后还要使得其具备异常处理, ...

  9. ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第五篇:MVC整合Ajax

    摘要      本文将从完成“输入数据验证”这个功能出发,逐渐展开ASP.NET MVC与Ajax结合的方法.首先,本文将使用ASP.NET MVC提供的同步方式完成数据验证.而后,将分别结合ASP. ...

随机推荐

  1. webpack的devServer配置错误

    首先声明,之前vue项目没有报错,做react项目这样配置就报错了. 一.问题描述 [HMR] Hot Module Replacement is disabled. 二.问题分析 不太理解控制台为什 ...

  2. ISP PIPLINE (五) Denoise

    what is the Denoise? Denoise就是图像去噪,平滑图像,并保留图像细节. why does Denoise? 图像在采集并转换为数字信号的过程会引入一些噪声,这些噪声会让图片看 ...

  3. Django——图书管理系统

    基于Django的图书管理系统 1.主体功能 1.列出图书列表.出版社列表.作者列表 2.点击作者,会列出其出版的图书列表 3.点击出版社,会列出旗下图书列表 4.可以创建.修改.删除 图书.作者.出 ...

  4. c#关键字和常用类型表快查

    类型 字节 取值范围 说明 bool 1 true/false/null 布尔类型 char 2 0x0000~0xffff Unicode 16 位字符 byte 1 0~255 无符号的 8 位整 ...

  5. scrapy模拟登录

    对于scrapy来说,也是有两个方法模拟登陆: 直接携带cookie 找到发送post请求的url地址,带上信息,发送请求 scrapy模拟登陆之携带cookie 应用场景: cookie过期时间很长 ...

  6. 1 开发环境 eclipse oomph版本 jdk1.8 lucene 6.6.0,luke6.6.0

    第一个jar  是分词器,后面的是lucene  解压出来的 路径如下: lucene-analyzers-common-6.6.0.jar:lucene-6.6.0/common/ lucene-a ...

  7. python dgango简介 安装 多表查询

    一.socket服务器 import socket sk=socket.socket() sk.bind(("127.0.0.1",8890)) sk.listen() while ...

  8. CentOS下添加用户并且让用户获得root权限

    转自:https://blog.csdn.net/tropicofcancer9/article/details/53926920 1.添加用户,首先用adduser命令添加一个普通用户,命令如下: ...

  9. maven jdk版本

    http://maven.apache.org/docs/history.html Maven Releases History Date format is: YYYY-MM-DD Maven 3 ...

  10. python 配置文件返回的两种方式,写法不一样而已

    配置文件如下: [MODE]mode:{ "register":"all"} 或者 mode = {"register":"all ...