zoukankan      html  css  js  c++  java
  • 【NET MVC】View

    通过阅读一些书籍,结合源代码,稍微深入的学习了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'loMicrosoft.NE1Framework{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类型继承自定义的类
  • 相关阅读:
    线程池的实现原理
    log4j 具体解说(不能再具体了)
    MyEclipse中背景颜色的设定
    cacheManager载入问题
    SAP 经常使用T-CODE
    Oracle 版本号说明
    用XMPP实现完整Android聊天项目
    选择如何的系统更能适合App软件开发人员?
    爱国者布局智能硬件,空探系列PM2.5检測仪“嗅霾狗”大曝光
    Innodb引擎状态查看
  • 原文地址:https://www.cnblogs.com/tao0622/p/5838439.html
Copyright © 2011-2022 走看看