• asp.net mvc webform和razor的page基类区别


    接触过asp.net mvc的都知道,在传统的webform的模式下,page页面的基类是这样声明的:

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage" %>
    View Code

    如果是partial view的话,则是这样声明的:

    <%@ Control Language="C#" Inherits="ViewUserControl<dynamic>" %>
    View Code

    可以知道如果传统的view的话是继承于ViewPage这个类,如果是partialView的话则是继承于ViewUserControl这个类。

    为了证明我们的分析是否正确,我们看一下asp.net mvc的源码,在源码中有一个WebFormView类,这个就是支持我们传统的web form的基类,我们来看一下它的RenderView是怎么实现的,顺便这里提一下,WebFormView继承于BuildManagerCompiledView,这个我们以后讨论。

    protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance)
            {
                ViewPage viewPage = instance as ViewPage;
                if (viewPage != null)
                {
                    RenderViewPage(viewContext, viewPage);
                    return;
                }
    
                ViewUserControl viewUserControl = instance as ViewUserControl;
                if (viewUserControl != null)
                {
                    RenderViewUserControl(viewContext, viewUserControl);
                    return;
                }
    
                throw new InvalidOperationException(
                    String.Format(
                        CultureInfo.CurrentCulture,
                        MvcResources.WebFormViewEngine_WrongViewBase,
                        ViewPath));
            }
    View Code

    我们可以清楚的看到,先对object instance判断是否是ViewPage类型,如果为空则判断是否是ViewUserControl类型,如果两者都不是则抛出异常,由此我们可以得知,传统的webform主要由这两个基类组成。在传统的asp.net webform是怎么的情况,还需要大家自己去论证。

    好了,我们对asp.net mvc webform进行了分析,以后如果要重写基类的话,只要根据具体的需要对ViewPage和ViewUserControl进行重写就行了。

    那么自从asp.net mvc 3.0以后微软推出一个新的视图引擎razor以后,他的基类结构是否发生变化?

    事实的确是这样的,当我们使用Razor引擎的时候,我们创建的.cshtml文件没有了之前类似webform的头部声明:

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage" %>
    View Code

    取而代之则是什么都没有,这一时让我们需要重写基类的童鞋们摸不着头脑,好了那让我们用同样的思路进行一下分析,razor的头部声明没有,不代表他不继承于基类,既然省略那么说明一个很直接的原因就是他们的view和partialview的头部声明应该是一样的,所以微软干脆就省去不写了。那为了论证我们的猜想是否正确,我们看一下源码。

    同样在源码中有一个RazorView类,这个和WebFormView是对应着的,他同样也继承于BuildManagerCompiledView类,同理让我们来看一下他的RenderView方法是如何实现的。

    protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance)
            {
                if (writer == null)
                {
                    throw new ArgumentNullException("writer");
                }
    
                WebViewPage webViewPage = instance as WebViewPage;
                if (webViewPage == null)
                {
                    throw new InvalidOperationException(
                        String.Format(
                            CultureInfo.CurrentCulture,
                            MvcResources.CshtmlView_WrongViewBase,
                            ViewPath));
                }
    
                // An overriden master layout might have been specified when the ViewActionResult got returned.
                // We need to hold on to it so that we can set it on the inner page once it has executed.
                webViewPage.OverridenLayoutPath = LayoutPath;
                webViewPage.VirtualPath = ViewPath;
                webViewPage.ViewContext = viewContext;
                webViewPage.ViewData = viewContext.ViewData;
    
                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);
            }
    View Code

    正如我们猜想的在RenderView方法中只看到一个WebViewPage的类,那么就说明Razor引擎的View和PartialView的基类进行了合并,其实我们可以通过扩展名也可以得知,因为razor的扩展名不管是view和partialview都是.cshtml,和之前webform的模式已经不同。

    既然razor进行了合并,那么他们的头部声明肯定都是一样的,所以微软就省去了这个环节。

    那么razor该如何重写基类呢,如果声明页面头部继承关系呢?

    同样我们继承于WebViewPage基类,然后在自己的view或者partialview的头部进行如下声明:

    @inherits CustomWebViewPage

    或者

    @inherits CustomWebViewPage<CustomModel>

    这样就可以实现同的自定义实现了,不过这里需要提一点,由于WebViewPage是一个abstract类型的类,所以不能直接实例化,那么一点继承的话,里面必须需要实现一个Excute方法。如果你声明的CustomWebViewPage也是一个abstract类型,则不需要重写,调用默认的实现就可以,但是如果不是则要自己去实现自定义的excute方法。

  • 相关阅读:
    QTableWidget清空
    SQLite查询表是否存在
    QSplitter测试
    Qto_CoveringBaseQuantities
    osg旋转
    Qto_CurtainWallQuantities
    没有理清的一段代码
    方块
    Qto_DoorBaseQuantities
    全微分在近似计算中的应用
  • 原文地址:https://www.cnblogs.com/ldyblogs/p/webform.html
Copyright © 2020-2023  润新知