ASP.NET MVC视图中的@Html.xxx(...)

 

问题

在视图页中@Html.xxx(...)是什么?如何被执行?

如下图所示:
  

解疑

视图页中@Html.xxx(...)涉及的内容有:

  • 视图页被编译后的类继承自 WebViewPage<T>:WebViewPage:WebPageBase:WebPageRenderingBase:WebPageExecutingBase
  • 在进行View呈现过程中,创建视图页对象实例,此时 初始化了一个HtmlHelper对象,并赋值给其父类的一个名为Html的属性,@Html.xxx(...)中的Html就是该属性
  • 视图页中的@Html.xxx(...),经过编译之后,则变成该视图页对象Execute方法中的一段代码,即:this.Write(this.Html.xxx(xxx));
  • xxx是HtmlHelper类的扩展方法

以@Html.TextBox(...)为例进行详细分析:

  在ASP.NET MVC 中,视图页都被编译成继承自WebViewPage<T>的类,而在进行 View呈现 的过程中,需要通过反射创建视图页类的实例(Object类型),然后再将该实例转换为WebViewPage类型,并进行一些初始化操作,就在初始化时,创建了HtmlHelper对象,并赋值给其属性Html。

public abstract class BuildManagerCompiledView : IView
{
public void Render(ViewContext viewContext, TextWriter writer)
{
if (viewContext == null)
{
throw new ArgumentNullException("viewContext");
} object instance = null;
//获取被编译的视图页(cshtml文件)的类型
Type type = BuildManager.GetCompiledType(ViewPath);
if (type != null)
{
//通过SingleServiceResolver利用反射和缓存的原理创建视图页的实例,过程类似SingleServiceResolver类对Controller的激活。
instance = ViewPageActivator.Create(_controllerContext, type);
} if (instance == null)
{
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources.CshtmlView_ViewCouldNotBeCreated,
ViewPath));
}
//执行RenderView方法
RenderView(viewContext, writer, instance);
}
}
public class RazorView : BuildManagerCompiledView
{
protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
//将视图页实例转换为WebViewPage对象。
WebViewPage webViewPage = instance as WebViewPage;
if (webViewPage == null)
{
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources.CshtmlView_WrongViewBase,
ViewPath));
}
webViewPage.OverridenLayoutPath = LayoutPath;//母板路径(在第二步中,创建RazorView对象时,由构造函数导入)
webViewPage.VirtualPath = ViewPath; //该视图路径
webViewPage.ViewContext = viewContext; //视图上下文,其中有TempData、controllerContext、ViewData等
webViewPage.ViewData = viewContext.ViewData; //WebViewPage对象初始化,执行创建3个xxHelper对象AjaxHelper、HtmlHelper、UrlHelper。
webViewPage.InitHelpers(); if (VirtualPathFactory != null)
{
webViewPage.VirtualPathFactory = VirtualPathFactory;
}
if (DisplayModeProvider != null)
{
webViewPage.DisplayModeProvider = DisplayModeProvider;
} WebPageRenderingBase startPage = null;
if (RunViewStartPages)
{
startPage = StartPageLookup(webViewPage, RazorViewEngine.ViewStartFileName, ViewStartFileExtensions);
}
//按层次结构处理视图页的内容。
webViewPage.ExecutePageHierarchy(new WebPageContext(context: viewContext.HttpContext, page: null, model: null), writer, startPage);
}
}
public abstract class WebViewPage : WebPageBase, IViewDataContainer, IViewStartPageChild
{
//省略其他代码...
public AjaxHelper<object> Ajax
{
get;
set;
} public HtmlHelper<object> Html
{
get;
set;
} public UrlHelper Url
{
get;
set;
} public ViewContext ViewContext
{
get;
set;
} public virtual void InitHelpers()
{
this.Ajax = new AjaxHelper<object>(this.ViewContext, this);
this.Html = new HtmlHelper<object>(this.ViewContext, this);
this.Url = new UrlHelper(this.ViewContext.RequestContext);
}
}

“_Index.cshtml”经编译后的结果为:

  如上图所示,“@Html.TextBox(‘txtUser’)” 经过编译后,就是去执行base.Html.TextBox("txtUser"),又由类继承关系可知,base.Html的值就是一个HtmlHelper对象(视图页对象转换为WebViewPage类型后,初始化时创建的)。而TextBox("txtUser"),则是HtmlHelper的扩展方法!

 InputExtensions

  代码中,TextBox等扩展方法最终调用InputHelper方法,从而生成对应字符串类型的html标签(如:<input type='text"...>),然后将标签封装到一个MvcHtmlString对象中,并返回。即:base.Html.TextBox("txtUser")的执行结果就是一个封装了html标签内容的MvcHtmlString对象。之后执行this.Write(base.Html.TextBox("txtUser"))时,会执行MvcHtmlString对象的 ToHtmlString()方法获取html标签,最终将标签内容写入到响应给客户端的内容中!

 IHtmlString
 HtmlString
 MvcHtmlString

以下展示如何从MmvHtmlString对象中得到被封装的html标签(如:<input type='text"...>),并写入到Http响应内容中!

最终,将生成的html标签以字符串的形式写入到Http响应内容中!

以上只对HtmlHelper的扩展方法TextBox进行了介绍,其他的扩展方法童鞋们自行补脑了!上述如有不适之处,请指正!!!

扩展:

  可以通过创建一个HtmlHelper的扩展方法,从而实现一个自定义控件!

 
 
分类: MVC
标签: ASP.NET MVC

MVC视图中的@Html.xxx(...)的更多相关文章

  1. ASP.NET MVC视图中的@Html.xxx(...)

    问题 在视图页中@Html.xxx(...)是什么?如何被执行? 如下图所示: 解疑 视图页中@Html.xxx(...)涉及的内容有: 视图页被编译后的类继承自 WebViewPage<T&g ...

  2. 在mvc视图中实现rdlc报表展示(补充)

    上篇: 在mvc视图中实现rdlc报表展示 在上一遍中,由于不知道如何在aspx.cs后台中实例化abp的IxxxAppService.cs的接口,我采取的方式是在视图页中把查询出的数据存储到aspx ...

  3. 在mvc视图中实现rdlc报表展示

    需求:在view视图页面中嵌入rdlc报表,rdlc的xml为动态传入的xml字符串.本项目是基于abp框架 可能出现问题: 1.rdlc报表是由asp.net的服务器控件ReportViewer来支 ...

  4. MVC视图中Html.DropDownList()辅助方法的使用

    我们先在控制器中准备好一个SelectList类型,然后通过ViewBag.List传入视图中.SelectList类型是ASP.NET MVC专门为列表有关的HTML辅助方法提供选项的,例如,Htm ...

  5. asp.net mvc视图中使用entitySet类型数据时提示出错

    asp.net mvc5视图中使用entitySet类型数据时提示以下错误 检查了一下引用,发现已经引用了System.Data.Linq了,可是还是一直提示出错, 后来发现还需要在Views文件夹下 ...

  6. 解决.NET Core MVC 视图中的中文被html编码的问题

    在  .net core mvc 视图输出 变量的时候 默认使用的是 UnicodeRanges.BasicLatin  进行的编码 所以 输出中文后在查看源码的时候是进过编码了的 . 解决方案 在 ...

  7. MVC视图中读取ViewBag传递过来的HashTable表数据

    视图中头部添加 @using System.Collections; 循环读取哈希表数据 <ul id="AccessView" class="sys_spec_t ...

  8. C#,MVC视图中把枚举转成DropdownList

    1.拓展EnumHelper public static class EnumHelper { // Get the value of the description attribute if the ...

  9. vs mvc 视图中找不到 viewdata viewbag的解决方案

    1.查看views下的web.config文件是否存在 2.检查config中system.web.mvc ,version中版本号与自己的vs内置mvc版本一致 迁移项目可能有此问题

随机推荐

  1. express: command not found.

    npm install -g express 可是不行.全局模式不行. With the release of Express 4.0.0 it looks like you need to do s ...

  2. Android监视返回键

    android在发展中,监视键返回到后事件经常被用来,在下面的例子来说明什么android返回键事件监听器. public class BackKeyTest extends Activity { / ...

  3. Nyoj 引水工程(最小生成树)

    描述 南水北调工程是优化水资源配置.促进区域协调发展的基础性工程,是新中国成立以来投资额最大.涉及面最广的战略性工程,事关中华民族长远发展.“南水北调工程”,旨在缓解中国华北和西北地区水资源短缺的国家 ...

  4. RQNOJ PID3 / Jam的计数法

    题目描述 Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字 ...

  5. Delegate成员变量和Event的区别

    上周五有同事问了我一个问题:Delegate和Event有什么区别?具体来说在设计一个类的时候,声明一个事件(Event)和声明一个Delegate类型的成员变量有啥区别.   我的第一反应是没啥区别 ...

  6. 使用CNN(convolutional neural nets)关键的一点是检测到的面部教程(四):学习率,学习潜能,dropout

    第七部分 让 学习率 和 学习潜能 随时间的变化 光训练就花了一个小时的时间.等结果并非一个令人心情愉快的事情.这一部分.我们将讨论将两个技巧结合让网络训练的更快! 直觉上的解决的方法是,開始训练时取 ...

  7. 【Leetcode】Sort List (Sorting)

    这个问题需要与归并排序排两个名单,基本思路分为切割与合并 合并后的代码Merge Two Sorted List里已经讲得非常清楚了. 所以这里直接给出代码. public ListNode merg ...

  8. robot framework用python扩展编写自定义library

    我的utils.py文件 #!/usr/bin/env python #-*- coding:utf8 -*- __version__ = '0.1' import sys reload(sys) s ...

  9. 异步编程(Async和Await)的使用

    .net4.5新特性之异步编程(Async和Await)的使用 一.简介 首先来看看.net的发展中的各个阶段的特性:NET 与C# 的每个版本发布都是有一个“主题”.即:C#1.0托管代码→C#2. ...

  10. JavasScript实现调查问卷插件

    原文:JavasScript实现调查问卷插件 鄙人屌丝程序猿一枚,闲来无事,想尝试攻城师是感觉,于是乎搞了点小玩意.用js实现调查问卷,实现了常规的题型,单选,多选,排序,填空,矩阵等. 遂开源贴出来 ...