【.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‘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类型继承自定义的类

时间: 2024-10-19 21:46:26

【.NET MVC】View的相关文章

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

1   概述 本篇文章主要从操作上简要分析Controller<=>View之间相互传值,关于页面之间传值,如果感兴趣,可参考我另外一篇文章ASP.NET 页面之间传值的几种方式 . Controller=>View:Model,ViewBag,ViewData,TempData,ViewBag=>ViewData,ViewData=>ViewBag,ViewModel,JqGrid,AJAX+第三方插件等: View=>Controller:QueryString,F

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

实现的方法: 1.在父级项目中 或者 每个微服务都引用的项目中添加实体类Resource 2.在父级项目中 或者 每个为服务都引用的项目中写一个工具类,作用是用来获取请求资源 3.在每一个微服务的启动类添加注解@RestController ,并且写一个请求方法调用 工具类的请求资源的方法 4.将获取到的JSON字符串 保存在文件中 5.最后,在需要存储这些信息到数据库中的对应微服务 提供一个请求方法,参数就传递这一个一个的JSON字符串,而请求方法做的事情就是解析JSON,并批量保存到对应数据

【IOS笔记】View Controller Basics

View Controller Basics   视图控制器基础 Apps running on iOS–based devices have a limited amount of screen space for displaying content and therefore must be creative in how they present information to the user. Apps that have lots of information to display

【Spring MVC】Spring MVC,阻止直接访问jsp,使用Interceptor登录拦截

问题描述: 在Java Web项目中,用户可访问Url一般只有一个,即index或login.而用户的其他Url请求都会引导到index页.如何来避免未登录用户直接访问Spring的Conroller和jsp文件? 解决方案: 一.阻止用户访问jsp. Spring的MVC模式是不提倡直接通过URL形式访问.jsp页面的,建议通过Controller跳转至View页面. 把jsp文件放在WEB-INF目录下,js和css等资源文件放在WEB-INF的同级目录下,WEB-INF对用户不可见,可以起

【Spring MVC】spring mvc中相同的url请求返回不同的结果

在项目中凡是使用Spring MVC这种控制器的,大多都是返回JSON数据对象,或者JSP页面. 但是相同的URL请求如何让他自动的选择放回的是什么? 在这里有由于鄙人没有亲自测试过,就不敢乱贴代码,只把别人写的引用一下,以防未来某天需要而忘却. 引用地址:http://my.oschina.net/wzlee/blog/262205

【spring mvc】framework-core 跨域 使用用例

1.引入jar文件 <dependency> <groupId>cn.bidlink.nbl</groupId> <artifactId>framework-core</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> 2.添加spring mvc interceptor配置到springmvc-config.xml文件 <mvc:in

【Android 动画】View Animation详解(一)

安卓平台目前提供了两大类动画,在Android 3.0之前,一大类是View Animation,包括Tween animation(补间动画),Frame animation(帧动画),在android3.0中又引入了一个新的动画系统:property animation,即属性动画.本篇文章主要介绍View Animation的基本使用方法与技巧,属性动画将在下一篇博文中介绍. Tween动画可以执行一系列简单变换(位置,大小,旋转,缩放和透明度).所以,如果你有一个TextView对象,您

【Spring MVC】 - @ModelAttribute使用

@ModelAttribute一个具有如下三个作用: ①绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑 定流程,而且自动暴露为模型数据用于视图页面展示时使用: ②暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用 对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping 注解的方法)之前,自动添加 到模型对象中,用于视图页面展示时使用: ③暴露@Request

【安卓笔记】view.getX和view.getTranslationX区别

1.view.getTranslationX计算的是该view的偏移量.初始值为0,向左偏移值为负,向右偏移值为正. 2.view.getX相当于该view距离父容器左边缘的距离,等于getLeft+getTranslationX. 示意图: 举例: 布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.an