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个方法都是会生效的