代码改变世界

MVC — 笔记

2008-06-26 22:13  Animax!  阅读(1115)  评论(0编辑  收藏  举报

MVCModel-View-Controller,它的主旨是把一个Web页面处理分开为三个相互协作的部分。

当一个请求进入时它首先会经过Routing的分析,把URL连接解析出对应请求的controlleraction,所谓的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);

        }

         这里出现了两个方法:IgnoreRouteMapRoute

         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规则的占位符的名称。需要注意的是在Routecontrolleraction是必定存在的,可以不在URL规则里面写{controller}{action} ,但是在默认值里面必须要有controlleraction

            routes.MapRoute(

                "Book",

                "Book/Add/{name}",

                new { controller = "Book", action = "Add" },

                new { httpMethod = "POST" });

上面的规则便是没有controlleraction的,但是需要在默认值里配置controlleraction

这规则中的约束是 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中使用BindingHelperExtensionsReadFromRequest扩展方法或使用UpdateFrom辅助方法获取数据值。

Controller中需要传递给View的数据对象可以使用ViewData来传递字典类型。也可以直接向View传递一个强类型,但是这需要View页面继承ViewPage的时候给定这个强类型。

ModelController

    // 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 MVCView页面都继承于ViewPage ,它是用于显示Controller中传递来的数据。

         把数据显示到View中最直接简单的办法是把Controller中传递到ViewData的数据直接取出来显示:

Controller

        public ActionResult Index()

        {

            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();

        }

View

<%= Html.Encode(ViewData["Message"]) %>

其中这里的HtmlHtmlHelper类,里面包含了各种HTML显示的帮助,例如这里的 Html.Encode 就是把ViewData["Message"] 中的内容翻译为HTML显示。

除了EncodeHtmlHelper自身还提供了ActionLink RouteLink 方法,用于页面重定向。

HtmlHelper还有很多辅助的扩展方法,例如:Form用于制造表单、SubmitButton 用于提交表单、Button按钮、CheckBox选择按钮等……

View中显示数据可以在页面中嵌入脚本,也可以使用控件,在aspx.cs文件里面进行数据绑定,绑定是只需要在ViewData 中把数据取出然后绑定即可。

MVC中可以创建用户控件,控件需要继承于ViewUserControl,控件中也可以绑定数据,和在View页面相似。

View 中使用控件直接使用HtmlHelper扩展方法 RenderUserControl引用MVC控件即可。