Mvc:MVC(Model-View-Controller)用于表示一种软件架构模式.它把软件系统分为三个基本部分:模型(Model),视图(View)和控制器(Controller)。
一:下面分层次的总结Controller 处理流程:
1. 页面处理流程
发送请求 –> UrlRoutingModule捕获请求 –> MvcRouteHandler.GetHttpHandler() –> MvcHandler.ProcessRequest().
2.MvcHandler.ProcessRequest() 处理流程:
使用工厂方法获取具体的Controller –> Controller.Execute() –> 释放Controller对象.
3.Controller.Execute() 处理流程
获取Action –> 调用Action方法获取返回的ActionResult –> 调用ActionResult.ExecuteResult() 方法.
4.ActionResult.ExecuteResult() 处理流程
获取IView对象-> 根据IView对象中的页面路径获取Page类-> 调用IView.RenderView() 方法(内部调用Page.RenderView方法)
通过对MVC源代码的分析,我们了解到Controller对象的职责是传递数据,获取View对象(实现了IView接口的类),通知View对象显示.
View对象的作用是显示.虽然显示的方法RenderView()是由Controller调用的,但是Controller仅仅是一个"指挥官"的作用, 具体的显示逻辑仍然在View对象中.
需要注意IView接口与具体的ViewPage之间的联系.在Controller和View之间还存在着IView对象.对于ASP.NET程序提供了WebFormView对象实现了IView接口.WebFormView负责根据虚拟目录获取具体的Page类,然后调用Page.RenderView().
二:ViewBag、ViewData、TempData的区别
1、ViewData
ViewData的生命周期和View相同, 只对当前View有效。
2、TempData
TempData保存在Session中, Controller每次执行请求的时候会从Session中获取TempData并删除Session。
获取完TempData数据后虽然保存在内部的字典对象中。
但是TempData集合的每个条目访问一次后就从字典表中删除。
也就是说TempData的数据至多只能经过一次Controller传递。
并且每个元素至多只能访问一次。
具体代码层面,Temp获取过程是通过SessionStateTempDataProvider.LoadTempData方法从ControllerContext的Session中读取数据,而后清除Session,所以TempData只能挎Controller传递一次
3、ViewBag
ViewBag 是 MVC3 新增语法,ViewBag 不再是字典的键值对结构,而是 dynamic 动态类型,它会在程序运行的时候动态解析。ViewBag和ViewData生命周期相同,也是对当前View有效,不同的是ViewBag的类型不再是字典的键值对结构,而是dynamic动态类型,属于MVC3里面新增的部分。
下面总结下MVC当中的传值
ViewData只能在当前action中有效,在呈现的视图中需要显式转换为对应的类型TempData可以挎action使用,但是只能使用一次,在呈现的视图中需要显式转换为对应的类型。
ViewBag 它是动态类型,在程序运行时解析,在呈现的视图中,不需要显式转换类型。
return View(model); //使用模型创建一个将视图呈现给响应的 System.Web.Mvc.ViewResult 模型。
View页面:@model 需要声名此模型的类型 (注:之所以写为模型(因为也可以为一个对象,一个泛型等等..)
三:Mvc3的Razor视图引擎
一直想总结下Razor这玩意,但是别人总结的太好了,我甚至想一字不漏的拷贝过来。不过东西始终是别人的,那么就自己重写一个来顺便总结吧。
引言:让我们看看我们如何使无意中接触到的Razor。
在创建mvc项目时,在向导中,可以选择使用哪个视图引擎开发
如图所示:可以选择Razor引擎。
1.@()代码块
用惯了这样的语法
<span>这是我的测试 @_test</span>
突然需要在测试的后边去掉空格有比较束手无策了,因为这样会将@符号当做文本来处理,此时就可以使用@()这个代码块了。
@("<span>这是我的测试"+@_test+"</span>")
2.@model 关键字的介绍
第一次接触,就是看着别人如何使用,然后自己就如何使用,可是为什么要这么使用就不知道了。所以就这里追述了下。
public ActionResult AlbumList() { var list = AlbumProvider.getAlbumbyId(1); return View(list); }
View方法里的需要接受的一个参数正是一个object类型的model.在视图文件中,获取到这个list就需要用到了@model
只是在它出现之前mvc开发人员是这样获取list对象的。
@inherits System.Web.Mvc.WebViewPage<IList<Album>>只不过因为冗长的原因,便提供了一个更清洁,更简洁的方式来表示你想在视图文件中使用强类型的模型类.
@model IList<Model.artAlbumInfo>
那么使用就是如下了
@{ foreach (var item in Model) { <span>作品数量:@item.worksNum</span> } }
By default, Razor will derive the view from the System.Web.Mvc.WebViewPage<TModel> base class.(默认情况下,剃刀是从哪个类下派生。)
总结 :@model让代码编写更干净,更简洁。上面的@ model关键字是一个小功能,但有助于很好地向视图文件更容易读取和写入。
一:@RenderSection
1:我的理解:@RenderSection在母版页中占个位,然后让使用此母版页的子页自己去呈现他们的Section。
2:但是当如果使用了_Layout.cshtml做母版页的页没有实现Section的话,子页的例如:index.cshtml页面@section SubMenu{...},就会抛出异常
此时可以用另外一个重载@RenderSection("SubMenu",false),第二个参数代表它不是必须的,就不会抛出异常。
3:当我在母版页定义了@RenderSection("SubMenu",false)的时候,我希望当所有子页都没有实现这个Section的时候,母版页能有自己呈现的内容
@if (IsSectionDefined("SubMenu")) { @RenderSection("SubMenu", false) } else { <p>SubMenu Section is not defined!</p> }
当然也可以写一个扩展方法:
public static HelperResult RenderSection(this WebPageBase page, string sectionName, Func<object, HelperResult> defaultContent) { if (page.IsSectionDefined(sectionName)) { return page.RenderSection(sectionName); } else { return defaultContent(null); } }
在母版页中:
@this.RenderSection("SubMenu", @<div>default section content</div>)
在子页面中的调用:
@section SubMenu{ <link href="/css/ment2.css" type="text/css" rel="stylesheet" /> }
二:
@RenderPage("~/Views/Shared/head.cshtml")
关于@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction 的区别
1、带有Render的方法返回值是void,在方法内部进行输出;不带的返回值类型为MvcHtmlString,所以只能这样使用:
@Html.Partial 对应 @{Html.RenderPartial(....);}
@Html.Action 对应 @{Html.RenderAction(....);}
2、Html.Partial可以直接提供用户控件名(view)作为参数,而Html.Action需要有对应的Action,在Action内部返回PartailResult(即retun PartialView())。
3、对于简单的没有任何逻辑的用户控件,推荐使用Html.Partial;对于需要设置一些Model的用户控件,推荐使用Html.Action。当然,有Model数据也是可以使用Html.Partial方法的,可以看方法的重载。
4、使用Html.Action有个好处,就是可以根据不同的场景选择不同的用户控件。
比如:
@Html.Action("UserInfoControl")
在对应的UserInfoControl这个Action中,在用户未登录的时候,可以retun PartialView("LogOnUserControl");登录后,可以retun PartialView("UserInfoControl");
两者都可以输出一个Partial视图;其区别如下:
1. Partial有返回值(MvcHtmlString);RenderPartial没有返回值(Void)。
那么在Razor中的用法:
@Html.Partial("test")
@{Html.RenderPartial("test");}
这两个表达式所做的事情是一样的。
还记得2011年底的时候,正好开始用mvc在实战中使用,当时一个问题就是有关请求一个view时,带参数过去。明明知道是仅仅需要一个ViewDataDictionary的实例,却纠结半天如何继续简略。
@{ ViewDataDictionary vd=new ViewDataDictionary(); vd.Add("type","1"); } @Html.Partial("upload",vd)
最后一想,不就是这样的吗。
@Html.Partial("upload",new ViewDataDictionary{{"type","1"}})
@Html.Partial("upload",new ViewDataDictionary (){{"type","1"}})
上面两个区别在哪里呢。
upload.chshtml页面使用:
上面type是key,1是value
@{
var a=ViewData["type"];
}
@a
MVC封装了太多的类供我们使用,纠结的就是矫情劲,如何能简洁的表述出来。
MVC-ActionResult的总结
所以有时候也就不用在意方法中指明的返回类型为什么和方法内部返回的不一样。
public static ActionResult goSuccess(string msg, string url) { dynamic dy = new System.Dynamic.ExpandoObject(); dy = new { _msg = msg, _url = url }; return new PartialViewResult { ViewName = "~/Views/Message/success.cshtml", ViewData = new ViewDataDictionary<dynamic>(dy) }; } public static ActionResult goError(string msg, string url) { dynamic dy = new System.Dynamic.ExpandoObject(); dy = new { _msg = msg, _url = url }; return new PartialViewResult { ViewName = "~/Views/Message/error.cshtml", ViewData = new ViewDataDictionary<dynamic>(dy) }; }
前台调用:
@model dynamic <span>@Model._msg</span>
当然需要了解有关ActionResult的知识,可以参考这里
http://www.cnblogs.com/celery94/archive/2011/01/12/1933541.html
有轮子就不必继续往下造了!