MVC — 笔记
2008-06-26 22:13 Animax! 阅读(1115) 评论(0) 编辑 收藏 举报MVC:Model-View-Controller,它的主旨是把一个Web页面处理分开为三个相互协作的部分。
当一个请求进入时它首先会经过Routing的分析,把URL连接解析出对应请求的controller和action,所谓的Action其实就是Controller中的一个方法。View 就是使用经过Controller处理的ActionResult 来进行显示。
MVC请求执行顺序图
Routing
Routing就是URL刚进入程序时所进行的路由解析操作,它的运作需要一张路由表RouteTable,通常RouteTable都会从Global中作全局配置。
Route的配置形式是使用以大括号标识的占位符和其它字符(如“/”、“.”、“-”)组成的路径来作为规则。
用ASP.NET MVC framework Preview 3 生成后Global中的代码如下:
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 = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
这里出现了两个方法:IgnoreRoute和MapRoute。
IgnoreRoute 是Preview 3中的新方法,它的作用是中止处理某些URL模式。
MapRoute 用于配置匹配的URL规则。
参数的作用按参数序是:规则的名字、以占位符组成的规则URL、默认值、约束。
这两个规则都是MVC提供的简化版扩展方法而不是Routing自己的方法,规则配置的顺序是会对结果产生影响的,Routing会在匹配到一个规制之后就不再继续查找匹配。
即是如果在RegisterRoutes方法的末尾添加上:
routes.MapRoute("ATest","{controller}/{action}");
那么这个ATest规制将无望被匹配,但Default 规则可以加上约束:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" },
new { controller = @""d$" }
);
把Default 规则的controller约束成只能匹配以数字结尾的controller时候ATest才可能被匹配到。
MapRoute的第三四个参数是匿名类型,属性的名字对应着的是URL规则的占位符的名称。需要注意的是在Route中controller和action是必定存在的,可以不在URL规则里面写{controller}、{action} ,但是在默认值里面必须要有controller和action。
routes.MapRoute(
"Book",
"Book/Add/{name}",
new { controller = "Book", action = "Add" },
new { httpMethod = "POST" });
上面的规则便是没有controller和action的,但是需要在默认值里配置controller和action。
这规则中的约束是 httpMethod = "POST",表示它只有Post过来的URL请求它才会匹配。
在占位符前加入*号,表明这个占位符匹配以后所有规则:
routes.MapRoute(
"catchall",
"{*catchall}",
new { controller = "Home", action = "Index" });
通常这是在Route表最后出现。
如果URL访问的是一个物理文件的路径时,Route默认是不会解析该URL的(能直接访问到物理文件),你可以使用RouteExistingFiles属性:
outeTable.Routes.RouteExistingFiles = true;
来使它不直接访问到物理文件。
Controller
Controller的作用是处理请求并把所需的数据提供给页面,Controller必须要以“Controller”来作为类名字的结尾,这是一个约定。每个Controller中的Action都会有一个对应的View页面,View的名称就是Action的名称。
在Controller里面提供了几个方法:
Redirect:重定向到指定的URL。
RedirectToAction:重定向到指定的Action。
RedirectToRoute:按指定Routes规则来重定向。
public ActionResult ToUrl()//地址重定向
{
return this.Redirect("URL");
}
public ActionResult ToAction()// Action重定向
{
return this.RedirectToAction("Action");
}
public ActionResult ToRoute()
{
return this.RedirectToRoute("RouteName");
}
一般来说一个Action都会使用View() 方法来作为返回值,View方法还可以直接传出一个强类型。Controller有一个重载方法:HandleUnknownAction用于在没有找到Action的时候作重定向用。
protected override void HandleUnknownAction(string actionName)
{
this.Response.Redirect("URL");
}
在View中需要传递参数到Controller可以在View中使用表单并把表单的Action设置成Controller中出来数据的Action名称,并在Controller中使用ReadFromRequest方法来获取View表单传入的数据。
<form action="ActionName" method="post">
....
</form>
在Controller中使用BindingHelperExtensions的ReadFromRequest扩展方法或使用UpdateFrom辅助方法获取数据值。
Controller中需要传递给View的数据对象可以使用ViewData来传递字典类型。也可以直接向View传递一个强类型,但是这需要View页面继承ViewPage的时候给定这个强类型。
Model和Controller:
// Model
public class TestModel
{
public int Content { set; get; }
public string Title { set; get; }
}
// Controller
public ActionResult Model()
{
TestModel model = new TestModel()
{
Content = 1,
Title = "ModelTest"
};
return View(model);
}
View继承于:ViewPage<TestModel>
View页面显示:
<%= this.ViewData.Model.Title %>
View
在Asp.net MVC中View页面都继承于ViewPage ,它是用于显示Controller中传递来的数据。
把数据显示到View中最直接简单的办法是把Controller中传递到ViewData的数据直接取出来显示:
Controller:
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
View:
<%= Html.Encode(ViewData["Message"]) %>
其中这里的Html是HtmlHelper类,里面包含了各种HTML显示的帮助,例如这里的 Html.Encode 就是把ViewData["Message"] 中的内容翻译为HTML显示。
除了Encode外HtmlHelper自身还提供了ActionLink 和 RouteLink 方法,用于页面重定向。
HtmlHelper还有很多辅助的扩展方法,例如:Form用于制造表单、SubmitButton 用于提交表单、Button按钮、CheckBox选择按钮等……
View中显示数据可以在页面中嵌入脚本,也可以使用控件,在aspx.cs文件里面进行数据绑定,绑定是只需要在ViewData 中把数据取出然后绑定即可。
MVC中可以创建用户控件,控件需要继承于ViewUserControl,控件中也可以绑定数据,和在View页面相似。
在View 中使用控件直接使用HtmlHelper扩展方法 RenderUserControl引用MVC控件即可。