MVC
MVC流程
说明:在MVC中,客户端的所请求的URL是被映射到相应的Controller去,然后由Controller来处理业务逻辑,或许要从Model中取数据,然后再由Controller选择合适的View返回给客户端。
1.传值
ViewBag,ViewData,TempData
**ViewBag和ViewData生命周期相同,仅对当前View有效,不同的是ViewBag的类型不再是字典的键值对结构,而是dynamic动态类型。
**ViewData是ViewDataDictionary 类型
**ViewBag是dynamic类型
public ActionResult Index() { ViewData["mytitle"] = "我是标题"; List<string> strs = new List<string> { "China","USA","DE","US"}; ViewData["jihe"] = strs; Dictionary<int, string> strss = new Dictionary<int, string>(); strss.Add(2, "China"); strss.Add(5, "DE"); strss.Add(7, "US"); ViewBag.adidasi = "阿迪达斯"; ViewBag.jihes = strss; return View(); }
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Index</h2> @foreach (var item in ViewData["jihe"] as List<string>) { <li>@item</li> } <hr> @ViewBag.adidasi @foreach (var item in ViewBag.jihes) { <li> @item.Key":"@item.Value </li> }
**TempData
1) TempData保存在Session中,Controller每次执行请求的时候,会从Session中先获取TempData,而后清除Session,获取完TempData数据,虽然保存在内部字典对象中,但是其集合中的每个条目访问一次后就从字典表中删除。
2)具体代码层面,TempData获取过程是通过SessionStateTempDataProvider.LoadTempData方法从ControllerContext的Session中读取数据,而后清除Session,故TempData只能跨Controller传递一次。
3)如果我们想读取TempData的值但是又不让它被删除,可以使用TempData.Peek("Key")方法。如果想再保持一次TempData里面的值,可以使用TempData.Keep("Key").
2.部分视图
RenderBody()
3.Razor工作原理
**如果要解析一段输出
<div> @foreach(var post in Posts) { <div>@post.Title</div> } </div>
**先转化成XML
<Document> <Markup><div>\r\n\t</Markup> <Statement> <Transition>@</Transition> <Code>foreach(var post in posts) { </Code> <Markup> <Markup><div></Markup> <Expression> <Transition>@</Transition> <ImplicitExpression>post.Title</ImplicitExpression> </Expression> <Markup></div></Markup> </Markup> <Code> } </Code> <Markup></div></Markup> </Statement> <Markup>\r\n</div></Markup> </Document>
**在转化成.net
public override void Execute() { WriteLiteral("<div>\r\n\t"); @foreach(var post in posts) { WriteLiteral("<div>"); Write(post.Title); WriteLiteral("</div>"); } WriteLiteral("\r\n</div>");
4.语法规则
C# 的主要 Razor 语法规则
Razor 代码封装于 @{ ... } 中
行内表达式(变量和函数)以 @ 开头
代码语句以分号结尾
字符串由引号包围
C# 代码对大小写敏感
C# 文件的扩展名是 .cshtml
5.扩展指令
5.1 @model
**使用@model关键字可以定义一个Action里所对应的一个模型(经常可以叫他实体类),其实是对动态变量进行实例化,这样就可以直接在cshtml文件中调用“Model”变量。而这个模型的实例,需要通过Controller进行传输,如果没有则“Model”将为null。
**模型可以是一个实体类,也可以是一个列表实例,字典对象都可以进行定义,但是和Controller中的Action传回来的实例一定要一样
public ActionResult UserInfo() { var id = Convert.ToInt32(Request.QueryString["id"] ?? "0"); var user = Users.GetUser(id); return View(user); }
@model MvcApplication1.Models.LoginModel <h2>Test</h2> @Model.Password
5.2 @section
**Razor视图引擎支持将View中的一部分内容分离出来,以便在需要的地方重复利用,减少了代码的冗余。
@section Header { <div class="view"> @foreach (string str in new [] {"Home", "List", "Edit"}) { @str } </div> } <div class="view"> This is a list of fruit names: @foreach (string name in Model) { <span><b>@name</b></span> } </div> @section Footer { <div class="view"> This is the footer </div> }
**我们通过@section标签加section的名称来定义一个Section,这里创建了两个section:Header 和 Footer,习惯上一般把section放在View文件的开头或结尾以方便阅读。下面我们在 /Views/Shared/_Layout.cshtml 文件中来使用它们。
**母版页
<body> @RenderSection("Header") <div class="layout"> This is part of the layout </div> @RenderBody() <div class="layout"> This is part of the layout </div> @RenderSection("Footer") <div class="layout"> This is part of the layout </div> </body>
5.3 @ helper
**在视图中可以定义一个方法,供多次使用
@{ Layout = "~/Views/Shared/_Layout.cshtml"; } @model MvcApplication1.Models.Person @helper Show() { <font color="red">我的名字叫:@Model.Name</font> string link = "<a href=\"#\">Goto</a>"; @Html.Raw(link) } @Show()
**我们其实可以将方法定义在视图模板外部,并且让它可以被所有的视图模板所公用。
**要实现这个功能,我们需要把定义helper方法的文件放在App_Code目录下。这个目录通常应该在项目根目录下。
**比如我创建了一个叫做“ScottGu.cshtml”的文件,并且定义了2个方法在里面(你可以在一个文件中定义任意多个helper方法):
一旦我们在App层面定义了这些方法,我们就可以在应用程序的任何视图模板中使用它们。
ScottGu.cshtml模板文件将会自动编译为一个叫做ScottGu的类,并且包含2个静态方法: “DisplayPrice” 和“AnotherHelper” 。