在Asp.net4和4.5中,新增了WebPages Framework,编写页面代码使用了新的Razor语法,代码更加的简洁和符合Web标准,编写方式更接近于PHP和以前的Asp,和使用 WebForms这种模仿Windows Form编程方式有了很大不同,不再有大量控件和控件生成的大量不够灵活的代码,但是同样可以使用Asp.net提供的大量类库和功能,可以说 WebPages框架融合了Asp、PHP和Asp.net的全部优点,又可使用C#和VB编程语言。一看到WebPages框架,我就马上有了深入学习 的兴趣,因为它和WebForms相比立刻就会让有完美主义情结的程序员们倾心。

但WebPages框架却并没有绑定Razor语法,它可以使用第三方的视图引擎。WebPages和Razor也并没有和Asp.net MVC具有必然的联系。在VS2012中默认的网站模板里面多了”Asp.net网站(Razor v2)“,可以根据Razor语法创建WebPage。

WebPages网站简介

WebPages网站包含多个cshtml或vbhtml页面,这些页面中使用Razor模板语法,整个网站的文件都在一个文件夹中,bin目录中 有各种要用到的dll,没有解决方案文件,解决方案文件在另外一个和网站同时创建的项目中,其中有packages目录以管理WebPages网站需要用 到的包。一个普通的cshtml页代码如下:

@{var db = Database.Open("StarterSite"); var users = db.Query("Select * From UserProfile"); var grid = new WebGrid(users); } <!DOCTYPE html> <html> <head> <title></title> </head> <body> @grid.GetHtml() </body> </html>

从中可以看到,这种编写方式和PHP、Asp很相似,但WebPages身后却是庞大的Asp.net类库。

WebPages框架相关配置

在WebPages网站的web.config中并没有什么特殊配置,在.net framework 4.0中的web.config中相关的配置如下:

<compilation><assemblies><remove assembly="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /><add assembly="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <add assembly="System.Web.WebPages.Deployment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </assemblies> </compilation> <httpHandlers> <add path="*.cshtm" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/> <add path="*.cshtml" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/> <add path="*.vbhtm" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/> <add path="*.vbhtml" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/> </httpHandlers>

其中没有相关buildProviders的配置也没有相关httpModules的配置,httpHandlers的配置还将其映射到了 HttpForbiddenHandler禁止访问。在IIS或IIS Express中的配置中也只有Asp.net4.0的ISAPI的配置而没有相关的httpModule。而WebForms在web.config中 配置有相应的httpHandler和buildProvider。那么WebPages框架是如何运行的,其和WebForms在哪里产生了不 同,WebPages框架是如何在Asp.net框架下实现的,这就需要进入WebPages框架进行探索。

WebPages框架自动运行过程

从web.config中的System.Web.WebPages.Deployment程序集开始,这个程序集dll有一个 Asp.net4.0新增的特性PreApplicationStartMethodAttribute,这个特性配置了一个静态方法以在程序启动之前自 动执行,特性如下:[assembly: PreApplicationStartMethod(typeof(PreApplicationStartCode), "Start")], 查看PreApplicationStartCode类的Start方法,其调用了StartCore方法,StartCore又调用了 LoadWebPages方法,其中实现的功能主要是获取所有和WebPages框架相关的dll并得到这些dll上配置的 PreApplicationStartMethodAttribute特性对应的启动方法并全部执行,具有这个特性的dll有 System.Web.WebPages、System.Web.WebPages.Razor和WebMatrix.WebData,我们主要关注前两个。

private static void LoadWebPages(Version version){  IEnumerable<Assembly> assemblies = Enumerable.Select<AssemblyName, Assembly>(AssemblyUtils.GetAssembliesForVersion(version),     new Func<AssemblyName, Assembly>(null, (IntPtr) LoadAssembly));     

  foreach (Assembly assembly in assemblies)   { BuildManager.AddReferencedAssembly(assembly);  }  foreach (MethodInfo info in GetPreStartInitMethodsFromAssemblyCollection(assemblies))  {  info.Invoke(null, null);  } } 

在System.Web.WebPages.Razor程序集上的启动方法代码如下:

public static class PreApplicationStartCode
{// Fields private static bool _startWasCalled; // Methods public static void Start() { if (!_startWasCalled) { _startWasCalled = true; BuildProvider.RegisterBuildProvider(".cshtml", typeof(RazorBuildProvider)); BuildProvider.RegisterBuildProvider(".vbhtml", typeof(RazorBuildProvider)); } } }

其注册了cshtml和vbhtml文件对应的BuildProvider为RazorBuildProvider,即编译Razor语法文件的提供程序。

在System.Web.WebPages程序集上的启动方法代码如下,这些启动类的名字和方法是一样的

public static class PreApplicationStartCode
{// Fields private static bool _startWasCalled; // Methods public static void Start() { if (!_startWasCalled) { _startWasCalled = true; WebPageHttpHandler.RegisterExtension("cshtml"); WebPageHttpHandler.RegisterExtension("vbhtml"); PageParser.EnableLongStringsAsResources = false;         //此行代码注册了WebPageHttpModule         DynamicModuleUtility.RegisterModule(typeof(WebPageHttpModule)); ScopeStorage.CurrentProvider = new AspNetRequestScopeStorageProvider(); } } }

其中最重要的功能就是自动注册了一个HttpModule,到此我们就可以知道WebPages页面的编译和处理已经有了着落了。接着查看WebPageHttpModule的代码,这个httpmodule注册处理了HttpApplication的PostResolveRequestCache,BeginRequest和EndRequest事件,这些代码会在用户请求cshtml和vbhtml页面时触发执行,在这个过程中WebPageHttpModule还会在WebPages网站首次启动的时候调用System.Web.WebPages.ApplicationStartPage.ExecuteStartPage方法,在PostResolveRequestCache事件处理代码中调用了WebPageRoute的方法,其中创建了处理页面的WebPageHttpHandler类。

internal static void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
{HttpContextBase context = new HttpContextWrapper(((HttpApplication) sender).Context);   new WebPageRoute().DoPostResolveRequestCache(context); }

internal void DoPostResolveRequestCache(HttpContextBase context)
{if (!this.IsExplicitlyDisabled) { string pathValue = context.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + context.Request.PathInfo; ReadOnlyCollection<string> registeredExtensions = WebPageHttpHandler.GetRegisteredExtensions(); WebPageMatch match = MatchRequest(pathValue, registeredExtensions, this.VirtualPathFactory, context, DisplayModeProvider.Instance); if (match != null) { context.Items[typeof(WebPageMatch)] = match; string path = "~/" + match.MatchedPath;         //是否在WebPages网站的web.config中明确配置了webpages:Enabled if (!WebPagesDeployment.IsExplicitlyDisabled(path)) { //创建WebPageHttpHandler IHttpHandler handler = WebPageHttpHandler.CreateFromVirtualPath(path); if (handler != null) { SessionStateUtil.SetUpSessionState(context, handler);             //替换web.config中配置的HttpForbiddenHandler  context.RemapHandler(handler); } } } else { string extension = PathUtil.GetExtension(pathValue); foreach (string str4 in registeredExtensions) { if (string.Equals("." + str4, extension, StringComparison.OrdinalIgnoreCase)) { throw new HttpException(0x194, null); } } } } }

WebPageRoute还实现了WebPages网站页面地址更加友好的功能,如不必带cshtml和vbhtml后缀即可访问相应页面,可采用filename/category/id之类的地址访问,通过添加xx.Mobile.cshtml即可自动实现切换到移动页的功能等。到此HttpHandler创建完毕之后,就开始执行页面,WebPages页面的基类是System.Web.WebPages.WebPage。

如果我们在WebPages网站的web.config里面配置了webpages:Enabled为false,那么再次访问cshtml或vbhtml时发现处理它们的是HttpForbiddenHandler。

<appSettings><add key="webpages:Enabled" value="false"/> </appSettings>

 无法提供此类型的页

至此,我们对WebPages框架的相关运行原理有了一个大概的了解。WebPages框架通过Asp.net4.0提供的PreApplicationStartMethodAttribute特性实现了HttpModule和BuildProvider注册,而不是通常的web.config配置文件,本文介绍的过程并不是绝对的,因为这个特性是可以被Asp.net Runtime自动识别和运行的,例如只要你引用了System.Web.WebPages就会执行其上配置的注册WebPageHttpModule的方法,其这些程序集上的启动方法都有判断机制防止重复执行。

和Asp.net MVC中的Razor视图引擎的关系

Razor并没有和MVC紧密耦合,其可以脱离MVC,也可以脱离WebPage框架。System.Web.MVC程序集上也有PreApplicationStartMethodAttribute特性,其中分别直接调用了System.Web.WebPages和System.Web.WebPages.Razor中的启动类以注册WebPageHttpModule和RazorBuildProvider,但MVC之中又继承了System.Web.Razor中的WebPageRazorHost类实现了自己特有的MvcWebPageRazorHost,相当于增加了新的功能以和MVC配合。

正如MVC中有多种不同的视图引擎一样,WebPages框架也不一定要使用Razor引擎,我们可以实现自己的BuildProvider来定义WebPage语法和解析生成.Net程序集。

结语

个人认为WebPages框架在人们越来越注重Web标准和前端UI的情况下,抛弃了WebForms有些笨重和不透明的编程方式,具有极大的灵活性同时又可以利用Asp.net强大的类库,后端的框架模型并没有变,但却让Asp.net程序员有了和PHP、Asp类似的快速编程体验。受够了WebForms输出代码的臃肿的程序员们,赶快学习WebPages吧:)

转载于:https://www.cnblogs.com/webenh/p/5741941.html

Asp.net WebPages框架运行原理浅析(转)相关推荐

  1. Springboot整合redis实现缓存及其缓存运行原理浅析

    声明:小白,学习阶段,主要目的是为了记录学习过程,本文仅供参考,如有不足的地方欢迎指出讨论交流 本文基于Springboot2.1.3版本开发: 准备阶段 首先是pom.xml文件所需的依赖: < ...

  2. SSL/TLS协议的运行原理浅析—https通信过程及CA证书诠释

    互联网是开放环境,通信双方都是未知身份,这为协议的设计带来了很大的难度.而且,协议还必须能够经受所有匪夷所思的攻击,这使得SSL TLS协议变得异常复杂.理清https原理与CA证书体系 互联网的通信 ...

  3. dedeCMS,标准的MVC框架运行原理和缓存

    2019独角兽企业重金招聘Python工程师标准>>> 1.织梦的工作原理:   a.模板引擎:   b.内核文件的载入.读取:   运行原理:url->配置文件->公共 ...

  4. Pytorch源码与运行原理浅析--网络篇(一)

    前言 申请的专栏开通了,刚好最近闲下来了,就打算开这个坑了hhhhh 第一篇就先讲一讲pytorch的运行机制好了... 记得当时刚刚接触的时候一直搞不明白,为什么自己只是定义了几个网络,就可以完整的 ...

  5. php框架laravel原理,Laravel框架运行原理

    写在前面: 使用任何框架,如果理解该框架原理,应用起来会更加得心应手. 一.生命周期 1. 入口文件: Laravel框架所有请求入口统一进入/public/index.php文件,请求通过Ngxin ...

  6. ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行

    之前两篇文章简析.NET Core 以及与 .NET Framework的关系和.NET Core的构成体系从总体上介绍.NET Core,接下来计划用一个系列对ASP.NET Core的运行原理进行 ...

  7. ASP.NET Core 运行原理解剖[4]:进入HttpContext的世界

    本系列文章从源码分析的角度来探索 ASP.NET Core 的运行原理,分为以下几个章节: ASP.NET Core 运行原理解剖[1]:Hosting ASP.NET Core 运行原理解剖[2]: ...

  8. ASP.NET Core 运行原理解剖[1]:Hosting

    SP.NET Core 是新一代的 ASP.NET,第一次出现时代号为 ASP.NET vNext,后来命名为ASP.NET 5,随着它的完善与成熟,最终命名为 ASP.NET Core,表明它不是 ...

  9. .NET1.1中预编译ASP.NET页面实现原理浅析[1]自动预编译机制浅析

    .NET1.1中预编译ASP.NET页面实现原理浅析[1]自动预编译机制浅析 .NET1.1中预编译ASP.NET页面实现原理浅析[1]自动预编译机制浅析 作者:&;nbsp来自:网络 htt ...

最新文章

  1. linux利用* vim提权,linux 通过suid vim.basic文件提权
  2. ElasticSearch安装拼音插件(pinyin)
  3. springboot的war和jar包
  4. ElasticSearch highlight搜索结果高亮显示(英文检索)
  5. 女朋友跟你说晚安之后仍然在线,我用Python制作脚本成功征服
  6. 神将三国账号服务器上限,神将三国角色上限怎么办 等级和统御上限怎么算
  7. android 垂直方向布局,Android详解4种基本布局
  8. amos里CFA可行性辨别结果怎么看_AMOS 中验证性因素分析(CFA)
  9. LeetCode 三等分(题解+优化过程)
  10. Mysq底层数据结构和优化整理
  11. .c与.cpp的区别解析
  12. Qt下载安装教程,windows10亲测可用,版本5.12.11
  13. 2020牛客暑期多校训练营Groundhog and Gaming Time(数学期望,线段树,逆元)
  14. 云编译DSM引导(学习记录)
  15. 计算机文件夹移动的实验原理,怎么移动电脑文件和文件夹
  16. 微软2009年10月MVP(最有价值专家)博客园选区候选人名单
  17. 【人工智能】— 逻辑Agent、一般逻辑、Entailment 蕴涵、命题逻辑、前向链接、反向链接、Resolution归结
  18. 施密特正交化(Schmidt)
  19. mac 时间机器 禁用_如何在Mac上禁用屏幕时间通知
  20. Hyper-V虚拟化

热门文章

  1. 中国第三位世界拳王诞生 徐灿夺得WBA羽量级金腰带
  2. 著名音频库多角度对比(多平台可用)
  3. Sklearn-RandomForest
  4. Python 类的特殊成员方法
  5. python (continue与break)区别
  6. 简单的横向ListView实现(version 4.0)
  7. 【Redis3】基于Redis sentinel的自动failover主从复制
  8. Javascript事件模型系列(一)事件及事件的三种模型
  9. 如何配置YUM本地更新源
  10. 通过命令管理Windows7桌面防火墙