4.控制器和视图
1)继承关系
新建项目,打开HomeController.cs。
public class HomeController : Controller 可以看到HomeController 类继承Controller,鼠标对着Controller 右击,点击转到定义。
public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer 来到Controller ,又继承了ControllerBase,继续对ControllerBase右键转到定义。
public abstract class ControllerBase : IController 来到ControllerBase ,又继承了IController ,继续对IController 右键转到定义。
到了IController ,只有一个Execute方法。
新建项目,打开HomeController。修改代码继承IController,右键点击IController,快速操作和重构-实现接口。
修改代码,输出一段html标签,运行,执行了Execute()。
2)同名action
新建的DefaultController,创建两个同名方法Index,区别是方法的重载不一样。
运行程序,地址栏输入/Default/Index/1,会不会访问第二个Index方法呢?
结果MVC不明确两个方法用那个。也说明了不凭参数重载定位方法!
我们需要用特性标志来声明方法才能定义名称相同的action方法。
1.在action方法上输入[NonAction]特性,说明此方法不是Action方法,程序就可以运行。
2.[HttpGet][HttpPost]接受请求方式特性。相同方法名可以根据get,post请求来区分进入那个action。默认是get。如果是在地址栏输入/Default/Index请求就是get操作,进入[HttpGet]特性的action。如果表单post提交数据到Index action,进入[HttpPost]特性的action。
3)映射参数
public ActionResult Index(int id) 中id的值可自动获取,获取的途径和优先级有:
1.表单psot提交的集合数据
2.由路由定义的数据
3.url地址栏末尾?id=2&ft=wefwefwef
修改一下/Default/Index的视图。
8-11行代码对ViewData["id"]的值做了判断,如果不为空,输出html标签和ViewData["id"]的值。
13-17行代码Html.BeginForm("Index", "Default", FormMethod.Post)创建了form标签<form action="/Default" method="post">
@Html.TextBox("id", "", new { style = "width:200px;" })创建了文本框标签<input id="id" name="id" style="width:200px;" type="text" value="" />
using可以为form 简写</form>结束标签,方便简洁。
这种在前台页面书写C#的语法叫Razor。
下面是w3school对Razor语法的介绍:
什么是 Razor ?
Razor 是一种允许您向网页中嵌入基于服务器的代码(Visual Basic 和 C#)的标记语法。
当网页被写入浏览器时,基于服务器的代码能够创建动态内容。在网页加载时,服务器在向浏览器返回页面之前,会执行页面内的基于服务器代码。由于是在服务器上运行,这种代码能执行复杂的任务,比如访问数据库。
Razor 基于 ASP.NET,它为 web 应用程序的创建而设计。它拥有传统 ASP.NET 标记的能力,但更易使用,也更易学习。
运行程序,地址栏输入/Default/Index。mvc访问到特性为[HttpGet]的Index action,显示视图。
在输入框输入”888”,提交。特性为[HttpPost]的Index action接受到了请求,映射id的值,这里文本框的”name”属性必须是”id”。再次显示Index视图,这次ViewData["id"]值不为空,就把<P>标签和ViewData["id"]的值显示出来了。
4)action常见的返回类型
前面我们action一直都是返回与action名称相同的view视图页面,它还可以返回其他东西,例如json,javascript,文件等。它们的父类都是ActionResult。
1.EmptyResult 不返回任何操作
2.JsonResult 返回Json
3.JavaScriptResult 返回JavaScript
JavaScriptView展示视图,JavaScript返回一个弹出消息。
JavaScriptView视图用ajax请求页面。
4.FileResult 返回MP3/视频文件
5.ContentResult 返回文本字符串
结果会被HTML解析
也可以返回json等 return Content(json, "application/json");
6.ViewResult 返回视图
ViewResult没有新建视图,返回到Index action执行。
有些地方想要输出html标签但只能输出字符串可用@Html.Raw(“html标签”)来展示
5)Razor
Razor为视图表示提供了一种精简的语法,最大限度地减少了语法和额外的字符。Razor中核心转换字符是”@”。
所有以@开头或@{/*代码体*/}(注:在@和{之间不得添加任何空格)的部分代码都会被ASP.NET引擎进行处理。
在@{}内定义两个变量。@{}在外面调用,后面无须加”;”。
如果想单独输出一个”@”可以用两个”@@”得出。
如果在@的前一个字符若是非空白字符,则 ASP.NET不会对其进行处理,比如邮箱123456789@qq.com。如果前面不想要空格,可用”@()”来指明内容。如果不用”@()”,上图@items.Length后面就必须用标点或页面元素标签来结束,否则出错。
Razor会在点字符处向后窥看,看到不是一些有效的标识符后,会转回标记模式。
6)HTML辅助方法(标签)
大部分的辅助方法都输出HTML标记,尤其是HTML辅助方法。例如前面的BeginFrom辅助方法可以用来为搜索表单构建一个强壮的表单标签,而不必写很多代码。
常用 的辅助方法创建HTML标签,这里只展示了最简单的用法。
链接的两种写法
自定义一个HTML辅助方法
新建类Help
需要扩展辅助方法,必须写this HtmlHelper,且只能出现在静态方法。MvcHtmlString.Create是对字符串进行Html编码返回。
对应视图引入命名空间
成功
7)布局
我们未创建过其他标签布局页面,但是每打开一个不是自己创建的布局页面,自己的html代码在中央。
其实使用的就是Shared文件夹下面的_Layout.cshtml。这是一个母版页。
Views文件夹下面的_ViewStart.cshtml。来指明了每一个自己创建的view视图要使用那个母版页。
如果不想用母版页或想用其他的可以在view页面定义。
新建一个MVC5布局页。名称_Layout1。
加入一个 <P>标签。
注释Layout = null;运行程序。地址栏输入/Default/index。看到了母版页的<p>标签。
在试试把Layout设置为null,运行。
现在我们知道了。布局母版页中@RenderBody()就是要来装载子视图页的。
在_Layout1.cshtml中输入。可用来呈现一个页面。
@RenderPage("~/Views/Home/About.cshtml")
运行,把about action的页面加载进来了。
@RenderPage("~/Views/Home/About.cshtml",new{name=”ftah”,age=”22”})。第二个参数是要传递给所呈现页的数据数组。可在呈现页about 中使用 @PageData[“name”]获取。
@RenderSection可以用来加载子页面中的一部分页面,修改Default/index视图
在模板页中添加@RenderSection("js",false)。false表示当子页面没有提供这个占位的内容”js”,也可以运行,视为非必须提供。
也可以通过@if(IsSectionDefined(“js”)){@RenderSection("js",false)}else{<p>黑乎乎</p>}来达到同样效果。
运行,地址栏输入/Default/index。
想呈现要通过控制器获取数据的视图(用户控件)呢。
用Html.RenderAction
@{Html.RenderAction("Index", "Render", new { name = "ftah", age = "22" });}
Html.RenderAction必须写在@{}内。
新建/Render/Index方法和视图。
视图内获取Html.RenderAction的传值。
运行,地址栏输入/default/index。成功获取用户控件和母版页的传值。