28.0 MVC5

第一部分: 1 MVC5:Controller、Action、View 2 IIS部署,Global、Log4 3 数据传值的多种方式 广义MVC(Model--View-Controller), V是界面 M是数据和逻辑 C是控制,把M和V链接起来 程序设计模式,一种设计理念,可以有效的分离界面和业务 狭义MVC,是web开发框架, V--Views 用户看到的视图内容 C---Controllers 决定用户使用哪个视图,还能调用逻辑计算 方法Action M--Models 数据传递模型,普通的实体 MVC就是返回页面? 不是的 返回html--string---json--xml--file--图片 WebApi是返回数据的,为啥不都用MVC算了 其实不管是aspx/ashx/webapi/mvc,都是使用Http协议 所以一切的请求都可以实现的! Aspx:属于比较重的,默认有页面的生命周期---前后融合,viewstate---跟cs是一一对应 Ashx: 属于轻量级的,没有页面的概念 MVC:前后分离的,C可以任意指定视图,可以一套后台多套UI WepApi:专人做专事儿,管道都是独立的;RESTful,没有action .net core二者又融合管道了 ViewData字典传值,里面是object,需要类型转换 ViewBag dynamic传值,可以随便属性访问,运行时检测 以上二者是会覆盖的,后者为准 model--适合复杂数据的传递,强类型 TempData--临时数据,可以跨action后台传递,存在session里面,用一次就清理掉 Views--Web.Config是配置视图文件 masterpage--layout 默认是_layout 可以自行指定 Global.asax--全局式 Application_Start 全局启动时执行,且只执行一次,非常适合做初始化---也可以静态构造函数 还可以有很多别的,下回分解 dynamic是个动态类型--运行时检测--编译时随便你写 利用委托的,性能比反射高,可以提供便利 弱类型语言的特点,方便做一些特殊处理 第二部分: 1 Route使用和扩展,Area 2 Razor语法,前后端语法混编 3 Html扩展控件,后端封装前端 4 模板页Layout,局部页PartialView MvcApplication--Application_Start--RegisterRoutes--给RouteCollection添加规则 请求进到网站--X--请求地址被路由按顺序匹配--遇到一个吻合的结束---就到对应的控制器和action 因为一个Web项目可以非常大非常复杂,多人合作开发,命名就成问题了,Area可以把项目拆分开,方便团队合作;演变到后面可以做成插件式开发: MvcApplication--Application_Start--AreaRegistration.RegisterAllAreas()---其实就是把SystemAreaRegistration给注册下---添加URL地址规则--请求来了就匹配(area在普通的之前) 众所周知,MVC请求的最后是反射调用的controller+action,信息来自于url+route,路由匹配时,只能找到action和controller, 其实还有个步骤,扫描+存储,在bin里面找Controller的子类,然后把命名空间--类名称+全部方法都存起来 a 控制器类可以出现在MVC项目之外,唯一的规则就是继承自Controller b Area也可以独立开,规则是必须有个继承AreaRegistration 增加区域后需要指定命名空间 Razor语法:cshtml本质是一个类文件,混编了html+cs代码 写后台代码:行内--单行--多行--关键字 后台代码写html:@: 闭合的html标签 <text></text> Html扩展控件:封装个方法,自动生成html 后端一次性完成全部内容,而且html标签闭合 我们还可以自行封装这种扩展方法 但是这个已经不流行了,就是UI改动需要重新发布 更多应该是前后分离,写前端的人是不会懂后端的写法 Layout Masterpage--layout 默认是_layout 可以自行指定 @Styles.Render("~/Content/css") 使用样式包 @Scripts.Render("~/bundles/modernizr") 使用js包 @RenderBody() 就是页面的结合点 @RenderSection("scripts", required: false) partialPage局部页---ascx控件,是没有自己的ACTION @{ Html.RenderPartial("PartialPage", "这里是Html.RenderPartial"); } @Html.Partial("PartialPage", "这里是Html.Partial") 子请求 @Html.Action("ChildAction", "Second", new { name = "Html.Action" }) @{Html.RenderAction("ChildAction", "Second", new { name = "Html.RenderAction" });} 有action,也可以传参数 [ChildActionOnly]//只能被子请求访问 不能独立访问 第三部分: 1 IOC和MVC的结合,工厂的创建和Bussiness初始化 2 WCF搜索引擎的封装调用和AOP的整合 3 HTTP请求的本质,各种ActionResult扩展订制 MVC使用EF6: 完成EF6引入和数据访问 依赖的EF需要引入--数据库连接需要配置 当然不是的,一直推崇IOC, MVC请求进来---路由匹配---找到控制器和Action---控制器是个普通的类,Action是个普通的实例方法 ---是不是一定有个过程,叫实例化控制器---但是现在希望通过容器来实例化这个控制器 路由匹配后得到控制器名称---MVCHandler---ControllerBuilder.GetControllerFactory()---然后创建的控制器的实例 DefaultControllerFactory默认的控制器工厂---把工厂换成自己实现的不就可以了?---ControllerBuilder有个SetControllerFactory 1 继承DefaultControllerFactory 2 SetFactory----实例化控制器会进到这里 3 引入第三方容器--将控制器的实例化换成容器操作 完成了MVC+IOC+ORM的结合 这个适合全部的控制器吗? 控制器不是用的抽象-实例的配置, 是直接构造类型的实例 第四部分: 1 列表绑定、增删改查 2 WCF搜索引擎的封装调用和AOP的整合 3 Ajax删除、Ajax表单提交、Ajax列表、Ajax三级联动 4 Http请求的本质,各种ActionResult扩展订制 怎么样完成一个功能: a Bussiness增加接口+实现 b IOC配置文件 c 注入到控制器 d 查询数据库,传递到前端,绑定一下 e 接受参数,拼装参数---- f 参数ViewBag传递到前端再绑定 g 分页使用pagedlist---返回数据用StaticPagedList--前端分页url带上参数--接受分页参数 h 分页点击后重置页码数,就是设置表单的action 接口服务查询,建议封装一下; 建议跟数据库查询独立分开; 也是接口+实现+model,然后就IOC 应用程序的配置文件需要加上服务相关 Ruanmou.Framework:通用的帮助类库,这里面放的是任何一个项目都可能用上的,这个类库可以被任何类库引用,但是自身不引用任何类库;只要是我用的东西,都得写在我自己里面;如果必须用到别的类库的东西,可以通过委托传递进来; Ruanmou.Web.Core:专门为MVC网站服务的通用的帮助 1 增删改一览,Ajax删除、Ajax表单提交、Ajax列表、Ajax三级联动 2 HttpGet HttpPost Bind ChildActionOnly特性解读 3 Http请求的本质,各种ActionResult扩展订制 4 用户登录/退出功能实现 Create时,会有两次请求,地址都是一个,也就是Action相同, 一个HttpGet 一次HttpPost MVC怎么识别呢?不能依赖于参数识别(参数来源太多不稳定) 必须通过HttpVerbs来识别, 如果没有标记,那么就用方法名称来识别 [ChildActionOnly] 用来指定该Action不能被单独请求,只能是子请求 [Bind]指定只从前端接收哪些字段,其他的不要,防止数据的额外提交 [ValidateAntiForgeryToken] 防重复提交,在cookie里加上一个key,提交的时候先校验这个 。。。filter特性 MVC支持了非常多的特性,靠的全部是反射,就能额外的去识别特性,去做点有意义的事儿 Ajax请求数据响应格式: 一个项目组必须是统一的,前端才知道怎么应付 还有很多其他情况,比如异常了--exceptionfilter--按照固定格式返回 比如没有权限--authorization--按照固定格式返回 Http请求的本质: 请求--应答式,响应可以那么丰富? 不同的类型其实方式一样的,只不过有个contenttype的差别 html---text/html json---application/json xml---application/xml js----application/javascript ico----image/x-icon image/gif image/jpeg image/png 这个等于是Http协议的约定,Web框架和浏览器共同支持的 其实是服务器告诉浏览器如何处理这个数据 从页面下载pdf 或者页面展示pdf 靠的就是contenttype application/pdf application/octet-stream MVC各种Result的事儿 Json方法实际上是new JsonResult 然后ExecuteResult 指定ContentType-application/json 然后将Data序列化成字符串写入stream 我们可以随意扩展的,只需要把数据放入response 指定好contenttype 第五部分: 1 用户登录/退出功能实现 2 AuthorizeAttribute权限验证 3 Filter注册和匿名支持 4 解读Filter生效机制 登陆后有权限控制,有的页面的是需要用户登录后才能访问的 需要在访问页面时增加登陆验证 也不能每个action都来一遍 自定义CustomAuthorizeFilter, 1 方法注册----单个方法生效 2 控制器注册--控制器全部方法生效 3 全局注册--全部控制器的全部方法生效 AllowAnonymous匿名,单独加特性是没用的 其实需要验证时支持,甚至说可以自定义一些特性一样可以生效 a 用户访问A页面--没有权限--去登陆--成功跳回A页面 前端更多加个参数 用session,验证失败记录url,登陆成功使用url b 如果是ajax请求时没登录,需要返回规定格式的Ajax数据 c 特性使用范围 希望特性通用在不同的系统,不同的登陆地址 Filter生效机制: 控制器已经实例化了-- ExecuteCore--找到方法名字--ControllerActionInvoker.InvokeAction ---找到全部的Filter特性---InvokeAuthorize--result不为空,直接InvokeActionResult --为空就正常执行Action 有了一个类型实例,有一个方法名称,希望你反射执行 在找到方法后,执行方法前---可以检测下特性 (1 来自全局 2 找控制器 3 找方法的) ---特性是我预定义--只找这三类---按类执行 ---定个标识,为空正常,不为空就跳转--正常就继续执行方法 第六部分: 1 Filter原理和AOP面向切面编程 2 全局异常处理:HandleErrorAttribute 3 IActionFilter IResultFilter扩展订制 4 Filter全总结,实战框架中AOP解决方案 AOP面向切面编程 Filter原理:控制器实例化之后---ActionInvoke前后---通过检测预定义Filter并且执行它---达到AOP的目的 开发日常工作:查bug 解决bug 写bug HandleErrorAttribute+Application_Error(粒度不一样) IActionFilter&IResultFilter a 避免UI直接看到异常 Global OnActionExecuting Controller OnActionExecuting Action OnActionExecuting Action真实执行 Action OnActionExecuted Controller OnActionExecuted Global OnActionExecuted 不同注册位置生效顺序--全局/控制器/Action 同一位置按照先后顺序生效 (不设置Order默认是1) 设置后是按照从小到大执行 俄罗斯套娃 ActionFilter能干啥? 日志 参数检测-过滤参数 缓存 重写视图 压缩 防盗链 统计访问量--限流 不同的客户端跳转不同的页面 异常--权限:当然可以做,但是不合适,专业的对口 filter真的这么厉害,有没有什么局限性??!! 虽然很丰富,但是只能是以Action为单位 Action内部调用别的类库,加操作,做不到! 这种就得靠IOC+AOP扩展 ActionFilter 即使Action返回string 甚至Null 4个方法都是会生效的