2012.7.5 开始学习MVC,本以为这个框架多难学,学下来的感受是其实也就是编写格式而已,和普通的webform有质的区别。顿时理解那句老话,世上无难事,只怕有心人。只要开始和坚持,那么结果一定不会差。好了,言归正传,下面开始记录学习MVC的一些学习要点,也许没那么系统,没书上那么循序渐进,具体以实例和不同要点记录下来,只为自己回头可以看看。如果有时间的话,一定回头改之,希望自己也能向那些大牛一样可以做一个系列。
1. MVC 介绍
MVC (Model,View,Controller),模型,视图,控制器。
模型主要负责处理数据;控制器负责接受web请求,控制器中的Action 负责返回某个View,View是显示的内容。
例: localhost:xxx/user/index 此处访问的是项目下 UserController下的index Action
而不像普通Webform框架下有具体的Aspx页面,localhost:xxx/user/index/a.aspx。 这个Url在webform下可以正常访问,在MVC框架下是不行的。
另外:MVC框架设计原则是拒绝 runat=”server” 此类框架的,所以最好不要在MVC框架的项目中不要使用这种控件。
2. MVC 框架学习
有很多MVC框架,譬如大家常说的:Struts2,Spring,Hibgrade.
本系列使用的是 微软自己的MVC框架------ Asp.net MVC 2.0.至于其他比较好的框架,大家可以直接学习,但是个人认为还是从 微软的MVC框架开始。 这就像 Javascrpt 和 Jquery ,extjs 框架一样,肯定学好了Javascript再去学Jquery,extjs 这样,肯定易如反掌。毕竟都是Javascript的封装而已,就像你自己写的特殊函数封装而已。
VS2008 简体中文版,打了sp1补丁后,装上MVC2.0 模版之后开始
模版下载链接:
1)新建MVC项目
如上图,项目目录组成:
Code 存放自定义的类(比如 User类,Filter类(后面介绍到));
Context存放CSS。
Model 数据模型 updatemodel等
Controllers 存放控制器,控制器name必须由名字+Controller 组成,而且名字要和Views中要有以这个名字命名的文件夹。如图有个UserContrller,则Views 同样有个 User文件夹。
Views存放视图 。 Views根目录下有几个文件夹,则项目应该就有几个Controller,而且名字要和Views子文件夹名字相同。 另:此目录下的Shared 存放公共模版。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
[HandleError]
[MvcApplication1.Code.ParamFilter]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
ViewData["TEST"] = "Viewdata_test";
MvcApplication1.Code.mycode code = new MvcApplication1.Code.mycode();
code.Name = "王先生";
code.Id = "001";
ViewData["user"] = code;
List<string> ViewDataList = new List<string>();
ViewDataList.Add("a");
ViewDataList.Add("b");
ViewDataList.Add("c");
ViewData["ViewDataList"] = ViewDataList;
//TempData["ddd"] = "ddd:为TempData,只能用1次";
//Response.Redirect("about");
return View(); //默认Home/index view
}
public ActionResult About()
{
return View();
}
}
}
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>html helper <%=Html.ActionLink("超级链接到about","about") %></h2>
<h2>url helper <%=Url %></h2>
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<h2><%=ViewData["TEST"]%></h2>
<h2><%foreach (string str in ViewData["ViewDataList"] as List<string>){%></h2>
<li>
<%=str%>
</li>
<%} %>
<h2><% =(ViewData["user"] as MvcApplication1.Code.mycode).Name %></h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>
</asp:Content>
以上就是大概情况。
小总结: localhost:3373/home/index
访问的是Controller文件夹下的HomeContrller控制器中的index action。显示的东西由view决定,具体显示哪个view由action决定(return view(“xx”))。
3. 关键要点
1) ViewData 传值 Contrller中的Action定义 ViewData[“name”]=”Mike”
View 使用 <%=ViewData[“name”]%>
例: Controller定义ViewData变量:
List<string> ViewDataList = new List<string>();
ViewDataList.Add("a");
ViewDataList.Add("b");
ViewDataList.Add("c");
ViewData["ViewDataList"] = ViewDataList;
View中使用ViewData变量:
<% foreach(string str in ViewData[“ViewDataList”] as List<string>){ %>
<li><%= str%></li>
<% } %>
2. TempData传值 类似 ViewData。
但是这个值只保存一次。Index action 定义了
TempData[“onlytime”]=”只能访问一次”; return view(“edit”)
则在 跳转到edit view 会显示tempdata值,刷新后就没了。
3.ViewData 其他传值方式 例如 类,只要在View端做好 类型转换就可,然后直接访问属性或者字段。
另:VS 自动生成属性快捷: prop+tab+tab
4. 重定向 (4种写法)
假如在UserContrller 中的 Index action 中重定向。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class UserController : Controller
{
//
// GET: /User/
public ActionResult Index()
{
return view(); //默认访问views文件夹下User文件夹下的index视图
return view(“xx”);
Response.Redirect(“xx”);
return Redirect(“xx”);
return RedirectAction(“eidt”,”home”);
}
}
}
注意:
return view(“xx”);
Response.Redirect(“xx”);
return Redirect(“xx”);
前3种方式,只能访问当前Controller 名字的View 视图。
return RedirectAction(“eidt”,”home”); --只有这个可以指定到别的 View
5. URLROUNTING 路径选择
Global.asax 定义。
默认的Url路径: localhost:3373/home/index 这个就是在 Global.asax 定义的。
如果Url这样才能访问:localhost:3373/home.Controller/index 就得修改Global
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication1
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}
}
修改并并运行:
routes.MapRoute(
"Default", // Route name
"{controller}.controller/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
则下图的Url无法访问
必须改成 user.controller才能访问。
6. Filer
决定是Action之前用,还是之后; 决定return view 之前,还是之后做。
定义Filer ,继承 System.Web.Mvc.ActionFilterAttribute ,然后重写4个方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication1.Code
{
public class ParamFilter:System.Web.Mvc.ActionFilterAttribute
{
public override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
}
public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
}
public override void OnResultExecuting(System.Web.Mvc.ResultExecutingContext filterContext)
{
//if (string.IsNullOrEmpty(filterContext.HttpContext.Request.QueryString["k"]))
//{
// throw new Exception("发生了一个错误");
//}
}
}
}
Controller 使用 Filer
在Controller 外加上 [MvcApplication1.Code.ParamFilter]
或在具体的Action 上加 [MvcApplication1.Code.ParamFilter]