通过阅读一些书籍,结合源代码,稍微深入的学习了Asp.Net MVC中的视图View

任何类型的响应都可以利用当前HttpResponse来响应,MVC可以通过Controller的Response属性和HttpContext属性以及ControllerBase的ControllerContext属性获得当前的HttpResponse

而.Net MVC把针对请求的响应实现封装在一个抽象类ActionResult中,实现方法是ExecuteResult

那么ExecuteResult方法如何被调用?

①首先创建ActionResult对象:Controller的属性ActionInvoker是实现了IActionInvoker的ControllerActionInvoker类或者AsyncControllerActionInvoker类,调用InvokeActionMethod方法或者BeginInvokeActionMethod方法

内部通过一个ActionDescriptor或者AsyncActionDescriptor实例执行其实例方法Execute或者BeginExecute获得Action方法的返回值,根据该返回值调用CreateActionResult方法创建ActionResult对象

②.将当前ControllerContext作为参数调用ActionResult的ExecuteResult方法

MVC提供的ActionResult的子类如下

①EmptyResult:Action方法返回值为void或者return null时候,都会转换成该对象

②ContentResult:如果Action的返回值不是一个ActionResult对象,那么默认会将返回值转换为string类型,并以此创建ContentResult对象

③FileResult:

文件的响应形式:内联和附件,默认是内联

如果是附件形式,FiledDownloadName属性指定文件名,响应报头添加一个名称为"Content-Disposition"报头,报头值的格式为"attachment;filename={FileDownloadName}"
三个FileResult子类:FileContentResult、FilePathResult、FileStreamResult
④JavaScriptResult
ContentType="application/x-javascript"
⑤JsonResult:默认情况不能作为对HTTP-GET请求的响应,设置JsonRequestBehavior.AllowGet允许GET请求属性
MaxJsonLength限制被反序列化和序列化生成的JSON字符串的长度,默认值为2097152
RecursionLimit设置被序列化对象和反序列化生成对象结构的允许的层级数
 
⑥HttpStatusCodeResult
StatusCode:响应状态码
StatusDescription:状态描述
该类的两个子类:HttpNotFoundResult("404,Not Found")和HttpUnauthorizedResult("401,Not Authorized")
 
⑦RedirectResult/RedirectPermentResult、RedirectToActionResult/RedirectToActionPermanentResult、RedirectToRouteResult/RedirectToRoutePermanentResult:重定向

302 Found:暂时重定向/301 Moved Permanently:永久重定向
 
⑧ViewResult:最常用的返回一个视图 例如return View();
首先看看View对象,什么是View对象?其实我们定义后缀为.cshtml或者.vbhtml的文件会被编译成一个View对象(类型名形如_Page_Views_ControllerName_ActionName_cshtml)
View的呈现是通过实现接口IView的方法 void Render(ViewContext viewContext, TextWriter writer)
View对象的获取是通过VirtualPathProviderViewEngine类,该类实现接口IViewEngine的FindPartialView和FindView方法
可是方法返回的都是ViewEngineResult对象,其实该对象是对View和ViewEngine的封装,属性SearchedLocations表示搜索的位置列表
 
静态类型ViewEngines维护一个全局ViewEngine列表
RazorViewEngine和WebFormViewEngine引擎间接继承VirtualPathProviderViewEngine,实现了CreatePartialView和CreateView方法
 
View对象的获取和View的呈现,最初是通过ViewResult执行ExecuteResult激活的
 
通过cshtml或者vbhtml文件定义的View能够被执行,必须先被编译成存在于某个程序集的类型,MVC采用动态编译的方式对View文件实施编译,和ASP.NET传统的编译方式一样,针对View的编译默认是基于目录的,也就是说同一个目录下的多个View文件被编译到同一个程序集中(程序集名称以"App_Web_"为前缀),该程序集是按需加载的,第一次访问才会加载
 
View编译后的程序集保存默认路径:% WinDit'lo\Microsoft.NE1\Framework\{Version No}\Temporary AS NET Files\
可自定义配置路径tempDirectory
 
以Cotroller=Demo5 Action=Action3为例
编译后的dll
使用Reflector反编译后
 
发现静态调用WriteLiteral()方法 动态代码调用Write()方法
View编译后的类型是WebViewPage<TModel>的子类,,该类又是WebViewPage的子类,TModel就是代表View的Model类型
 
WebViewPage类定义
WebViewPage的基类是WebPageBase,View编译后的类型都具有这些方法,
所以布局文件使用@RenderBody @RenderSection就是对这些方法的调用
在视图View中@section sectionName{...}的语句最终都转换成方法DefineSection的调用
通过IsSectionDefined(string name)方法可以判断指定名称的Section是否被定义
@RenderBody()定义了Body的内容,View中没有显示指定Section名称的内容被默认作为Body的内容
 
最后具体分析下Razor引擎的执行的过程是啥?
1.首先ViewResultBase中的ExecuteResult方法执行,调用 FindView(context)方法
2.FindView(context)方法在ViewResultBase子类ViewResult中被重写
3.根据.cshtml和vbhtml的后缀,最终会选择RazorViewEngine,调用RazorViewEngine的FindView方法,实质调用它的父类VirtualPathProviderViewEngine的FindView,
该方法内部调用了CreateView方法创建View对象,RazorViewEngine重写了父类方法,所以创建的是一个RazorView对象
4.到此第一个步骤(1,2,3)执行完毕,获得一个封装了RazorView对象的ViewEngineResult对象
5.执行到View.Render()方法,由于View是RazorView对象,所以调用的RazorView的Render()方法
6.看看RazorView类的定义,并未找到Render()方法,继续看其父类BuildManagerCompiledView
7.BuildManagerCompiledView类中定义了Render()方法
8.从RazorView的RenderView()方法中查看可知,上述的instance其实是一个WebViewPage实例
9.WebViewPage的ExecutePageHierarchy()方法内部调用Execute()方法
10.该方法在View编译后的类中重写
 
11.Razor引擎大致渲染过程结束
 
可以通过在View上运用@inherits指令让动态编译生成的View类型继承自定义的类

【NET MVC】View的更多相关文章

  1. 【Spring MVC】Properties文件的加载

    [Spring MVC]Properties文件的加载 转载:https://www.cnblogs.com/yangchongxing/p/10726885.html 参考:https://java ...

  2. 【Mock MVC】使用学习

    [Mock MVC]使用学习 转载:https://www.cnblogs.com/yangchongxing/p/10658311.html

  3. 【swagger】1.swagger提供开发者文档--简单集成到spring boot中【spring mvc】【spring boot】

    swagger提供开发者文档 ======================================================== 作用:想使用swagger的同学,一定是想用它来做前后台 ...

  4. 【ASP.NET MVC】View与Controller之间传递数据

    1   概述 本篇文章主要从操作上简要分析Controller<=>View之间相互传值,关于页面之间传值,如果感兴趣,可参考我另外一篇文章ASP.NET 页面之间传值的几种方式 . Co ...

  5. 【MVC】View与Control之间数据传递

    1. Controller向View传递数据 使用ViewData传递数据[弱类型,字典型ViewDataDictionary] ViewData[“Message_ViewData”] = “ He ...

  6. 【MVC】View的使用

    /Views/_ViewStart.cshtml 文件会在其他视图文档被加载之前被载入,代码如下: @{ Layout = "~/Views/Shared/_Layout.cshtml&qu ...

  7. 【spring】【spring mvc】【spring boot】获取spring cloud项目中所有spring mvc的请求资源

    实现的方法: 1.在父级项目中 或者 每个微服务都引用的项目中添加实体类Resource 2.在父级项目中 或者 每个为服务都引用的项目中写一个工具类,作用是用来获取请求资源 3.在每一个微服务的启动 ...

  8. 【循序渐进MVC】第一回——一物多用Project.json依赖关系之dependencies节点

    Project.json统一了ASP.NET vNext之前版本的packages.config.NuGet 配置(nuspec)以及项目文件(csprojs):并集成在Project.json中. ...

  9. 【IOS笔记】View Controller Basics

    View Controller Basics   视图控制器基础 Apps running on iOS–based devices have a limited amount of screen s ...

随机推荐

  1. Metaio获取当前追踪的对象的方法

    重写 onTrackingEvent获取TrackingValues集合,然后通过TrackingValues的state属性的isTrackingState()方法判断是否为追踪状态,或者直接使用s ...

  2. 浅析PHP中for与foreach两个循环结构遍历数组的区别

    遍历一个数组是编程中最常见不过的了,这里跟大家讨论下for和foreach两种方法.用这两种方法执行遍历的场景太多太多了,这里我们只针对以下两个数组作为例子来讨论.所谓管中窥豹,多少能理清一点两者的区 ...

  3. LA

    grmon -altjtag -u 公式rand()%(b-a),是求范围随机数的计算公式,%是做求余运算,正整数对n求余的范围肯定是在0~n-1之间,也就是rand()%(b-a)的范围是0~b-a ...

  4. CMS模板引擎:XHtmlAction

    前言: 先说说大伙关心的工作上的事,在上家公司任了一个多月的技术经理后,和公司中止了合作关系. 主要原因在于一开始的待遇没谈的太清楚: 1:没有合同,没有公积金,连社保也没交. 2:工资的30%变成了 ...

  5. ASP.NET Core中显示自定义错误页面-增强版

    之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...

  6. Expert 诊断优化系列-------------针对重点语句调索引

    上一篇我们说了索引的重要性,一个索引不仅能让一条语句起飞,也能大量减少系统对CPU.内存.磁盘的依赖.我想上一篇中的例子可以说明了.给出上一篇和目录文链接: SQL SERVER全面优化------- ...

  7. CI-持续集成(2)-软件工业“流水线”技术实现

    1   概述 持续集成(Continuous Integration)是一种软件开发实践.在本系列文章的前一章节已经对其背景及理论体系进行了介绍.本小节则承接前面提出的理论构想进行具体的技术实现. & ...

  8. ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步

    一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...

  9. Redis系列(六)-SortedSets设计技巧

    阅读目录: 介绍 Score占位 更多位信息 总结 介绍 Redis Sorted Sets是类似Redis Sets数据结构,不允许重复项的String集合.不同的是Sorted Sets中的每个成 ...

  10. Guava库介绍之集合(Collection)相关的API

    作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 本文是我写的Google开源的Java编程库Guava系列之一,主要介 ...