热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

 问题在视图页中@Html.xxx()是什么?如何被执行?如下图所示:解疑视图页中@Html.xxx()涉及的内容有:视图页被编译后的类继承自 WebViewPage<T>:WebViewPage:WebPageBase:WebPageRenderingBase:WebPageExecutingBase在进行View呈现过程中,创
 

问题

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

如下图所示:
  MVC视图中的@Html.xxx(...)
    

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

解疑

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

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

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

ASP.NET MVC视图中的@Html.xxx(...)
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);
    }
}
MVC视图中的@Html.xxx(...)
    

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

ASP.NET MVC视图中的@Html.xxx(...)
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);
    }
}
MVC视图中的@Html.xxx(...)
    

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

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

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

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

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

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

 InputExtensions

  代码中,TextBox等扩展方法最终调用InputHelper方法,从而生成对应字符串类型的html标签(如:),并写入到Http响应内容中!MVC视图中的@Html.xxx(...)
    

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

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

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

扩展:

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

 
 
MVC
ASP.NET MVC

问题

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

如下图所示:
  MVC视图中的@Html.xxx(...)
    

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

解疑

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

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

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

ASP.NET MVC视图中的@Html.xxx(...)
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);
    }
}
MVC视图中的@Html.xxx(...)
    

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

ASP.NET MVC视图中的@Html.xxx(...)
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);
    }
}
MVC视图中的@Html.xxx(...)
    

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

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

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

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

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

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

 InputExtensions

  代码中,TextBox等扩展方法最终调用InputHelper方法,从而生成对应字符串类型的html标签(如:),并写入到Http响应内容中!MVC视图中的@Html.xxx(...)
    

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

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

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

扩展:

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


推荐阅读
author-avatar
Rockets马丁
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有