codebehinde与codefile原理转 codebehind

当我撰写本专栏的时候,Microsoft® .NET Framework 2.0 和Visual Studio®2005的候选版本已经“出炉”了,当您阅读到本文时,它们都已经投入使用。这一切似乎等待了很长时间。
  我还记得在 2003 年的 8 月坐在 Microsoft 公司的一个房间内倾听 Scott Guthrie和其他人(包括我的同事 Rob Howard,他也是专栏作家)介绍 ASP.NET 2.0的大量新功能。他们演示了一个又一个功能,这些功能令我们非常吃惊,因为它们极大地简化了 Web开发,而且是以可插入和可扩展的方式实现的,因此在开发过程中能够以任何所需级别进行更改。

  后续测试版本中进行了大量更改,多数是以修改、错误修复和控件附加的形式进行的。但是,有一个功能(代码隐藏模型)自从第一个预览版以来已经进行了大量更改,这主要是为了响应客户的反馈。现在即将发布之时,我想利用这个机会描述一下这个新的代码隐藏模型、它的基本原理,以及Web 开发人员将如何使用它。我也会介绍该模型的一些潜在的副作用以及如何在设计中解决它们。请注意,ASP.NET 2.0运行时完全支持 1.x 模型,因此针对 1.x 编写的应用程序可以在无需修改的情况下直接运行。

  代码隐藏

  虽然该代码隐藏模型在 2.0中是不同的,但是它的语法已经进行了少量更改。实际上,该更改十分细微,如果您不仔细查看,甚至都无法注意到它。显示新的代码隐藏语法:

Default.aspx

<%@ Page Language="C#"
CodeFile="Default.aspx.cs" Inherits="MsdnMag.Default"%>

Default.aspx.cs

namespace MsdnMag
{
publicpartial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}

  该模型与以前的 1.x 模型有两个区别 — 在 @ Page 指令中引入了CodeFile 属性,以及将代码隐藏类声明为部分类。当开始生成该页时,您将注意到另一个区别 —服务器端控件不再需要在代码隐藏类中显式声明,但是您仍然能够以编程方式完整地访问它们。例如,中的窗体有若干个在代码隐藏文件中以编程方式使用的服务器端控件,但是您可以注意到,代码隐藏类中缺少任何显式控件声明。

Default.aspx

<%@ Page Language="C#"
CodeFile="Default.aspx.cs" Inherits="MsdnMag.Default"%>
<!DOCTYPE html PUBLIC "...""...">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>UntitledPage</title>
</head>
<body>
<form id="form1"runat="server">
<div>
Enter your name:
<asp:TextBox ID="_nameTextBox" runat="server"/><br />
<asp:Button ID="_enterButton" runat="server"
Text="Enter" OnClick="_enterButton_Click"/><br />
<asp:Label ID="_messageLabel" runat="server"/>
</div>
</form>
</body>
</html>

Default.aspx.cs

namespace MsdnMag
{
public partial class Default :System.Web.UI.Page
{
protectedvoid _enterButton_Click(object sender, EventArgs e)
{
_messageLabel.Text = "Hello there " + _nameTextBox.Text +"!";
}
}
}

  其中的原因与应用于代码隐藏类的部分关键字有关。除了使用呈现该页的方法将.aspx 文件转换为一个类定义(正如它已经做的一样),ASP.NET现在也为包含受保护控件成员变量声明的代码隐藏类生成一个同辈部分类。然后,您的类与该生成的类定义一起编译,并用作针对 .aspx文件生成的类的基类。结果是,您基本上以经常使用的方式编写代码隐藏类,但是您不再需要声明(或让服务器为您声明)服务器端控件的成员变量声明。这一直是1.x 中一个不太稳定的关系,因为如果您无意间修改了一个控件声明,使得它不再与该窗体上所声明控件的 ID匹配,就会突然停止工作。现在,成员变量以隐式方式声明并始终是正确的。显示所涉及类集的一个示例:

Class for ASPX file generated byASP.NET

namespace ASP
{
public classdefault_aspx : MsdnMag.Default
{
...
}
}

Sibling partial class generated byASP.NET

namespace MsdnMag
{
public partial class Default :IRequiresSessionState
{
protectedTextBox _nameTextBox;
protectedButton _enterButton;
protectedLabel_messageLabel;
private HtmlForm form1;
...
}
}

Codebehind partial class that youwrite

namespace MsdnMag
{
public partial class Default : Page
{
void_enterButton_Click(object sender, EventArgs e)
{
_messageLabel.Text = "Hello there " + _nameTextBox.Text +"!";
}
}
}

  请注意,该部分类模型仅当在 @ Page 指令中使用 CodeFile关键字时使用。如果使用不带 CodeFile(或者带有 src 属性)的 Inherits 关键字,ASP.NET 会使用 1.x代码隐藏类型并简单地将类设置为 .aspx 文件的唯一基类。此外,如果您根本没有代码隐藏,则类生成与它在 1.x中的操作将完全相同。由于 ASP.NET 2.0 向后与 1.x 兼容,因此现在有大量代码隐藏选项供您使用。

  Visual Studio 2005 将使用任何 Web窗体新的部分类隐藏模型,而且如果您使用转换向导,它也将很好地转换 Visual Studio .NET 2003项目以便使用新模型。因为 ASP.NET 2.0的一些新功能依赖于它的原因,所以如果可能,最好将所有文件转换为新代码隐藏模型(如果使用 VisualStudio,那么转换几乎是唯一的选择,因为 Visual Studio 2005 不会打开未转换的 1.x 项目)。例如,对Profile 属性包的强类型访问添加到 2.0 中代码隐藏类的同辈部分类中,但是如果您使用 1.x代码隐藏模型,则该强类型访问器直接添加到 .aspx生成的类定义中,而且对于代码隐藏类不可用。这也适用于强类型的母版页和以前的页访问。

  编译

  此时,您可能想知道,为什么 ASP.NET小组非要使用这个新代码隐藏模型来使用继承。ASP.NET 除了将来自 .aspx文件的方法呈现为部分类(然后这些类与简化的代码隐藏类合并)之外,还可以轻松生成所有控件变量声明。这就是 Windows 窗体在.NET Framework 2.0中的工作方式。设计器生成的所有代码被放置在同辈部分类(然后该类与您的应用程序逻辑合并)中,事件处理程序被放置在窗体驱动的单个类中,从而在无需借助于继承的情况下,在计算机生成的代码和开发人员代码之间创建一个完全的分离。

  嗯,ASP.NET 2.0 中代码隐藏的原始实现也执行此操作 —代码隐藏类只是一个与分析的 .aspx文件类定义合并的部分类。它简单有效,但遗憾的是它不够灵活。该模型的问题在于,预编译的二进制程序集中的代码隐藏文件不再能够与完整的.aspx文件一起部署,因为它们现在必须同时编译(使用部分类的一个限制是,一个类的所有部分必须在单个编译中合并,而且类定义无法跨越程序集)。对于许多开发人员而言,该限制是无法接受的,因为他们已经习惯于将二进制代码隐藏程序集与完整的.aspx 文件一起部署,后者随后会进行适当的更新而不必重新编译。实际上,这就是默认情况下 Visual Studio .NET2003 中使用的模型,而且在实践中非常流行。

  由于重新引入了继承模型并将部分类移到基类中,.aspx文件现在可以从代码隐藏类中进行独立部署和编译。为此,您需要某种方式在编译或部署过程中生成同辈的部分类,后者包含控件变量声明,因为在过去这一直是针对请求进行的。走近ASP.NET 编译器。

  在 ASP.NET 2.0 中,ASP.NET 编译器(aspnet_compiler.exe) 最初作为完全预编译整个站点的一种方式引入,从而使得只部署二进制程序集成为可能(甚至也对.aspx 和 .ascx文件进行预编译)。这是非常吸引人的,因为它消除了发出请求时的任何按需编译,从而消除了目前在一些站点上可以看到的第一个部署后点击。它也使得对已部署站点进行修改更加困难(因为您无法打开.aspx 文件并更改内容),当部署只想通过标准部署过程更改的应用程序时,这是很吸引人的。ASP.NET 2.0的发布版本提供的编译器支持仅支持二进制的部署模型,但是它也进行了增强以支持可更新的部署模型,其中站点中的所有源代码预编译为二进制程序集,但是所有.aspx 和 .ascx 文件都基本保持完整,以便可以在服务器上进行更改(针对 .aspx 和 .ascx 文件的更改,涉及移除的CodeFile 属性以及进行修改以包括程序集名的 Inherits属性)。由于在代码隐藏模型中重新引入了继承,因此该模型是可能的。这样,包含控件声明的同辈部分类可以独立于实际的 .aspx文件类定义生成和编译。


图 4 使用 aspnet_compiler.exe进行二进制部署

  图 4 显示使用二进制部署选项对 aspnet_compiler.exe实用工具的调用,以及针对部署目录的结果输出。请注意,该部署目录中的 .aspx文件只是没有内容的标记文件。它们之所以位于那里,是为了确保 IIS 应用程序中 .aspx 扩展的“Check that fileexists”选项进行设置后,带有终结点名称的文件可用。PrecompiledApp.config文件用于跟踪应用程序的部署方式,以及 ASP.NET 是否需要在请求时编译任何文件。要生成“可更新的”站点,需要将一个 -u添加到命令行,得到的 .aspx 文件将包含它们的原始内容(而不是空的标记文件)。请注意,该功能也可以通过 Visual Studio2005 的 Build | Publish Web Site 菜单项以图形方式访问,如图 5 所示。该命令行工具和 VisualStudio 都依赖于 System.Web.Compilation 命名空间的 ClientBuildManager类提供该功能。


图 5 Visual Studio 2005 中的 Build | PublishWeb Site 工具

  使用手边的 aspnet_compiler实用工具,您无需担心应用程序的大体部署方式就可使其运行,因为任何站点都能以下面三种方式之一进行部署 —全源、全二进制或可更新(二进制文件中的源代码和源代码中的 .aspx 文件)—无需对开发中使用的页面属性或代码文件进行任何更改。这在以前的 ASP.NET 版本中是不可能的,因为您必须在开发时决定是否使用 src属性来引用代码隐藏文件,或者预编译它们并将程序集部署到 /bin 目录。完整的二进制部署甚至不是一个选项。

  程序集生成

  既然编译为程序集可以在三种情况下发生(由开发人员显式进行,使用aspnet_compiler.exe,或者在请求处理中进行),因此了解文件到程序集的映射变得更为重要。实际上,根据编写页面的方式,您实际上可以得到一个应用程序,在作为全源或全二进制部署时,该应用程序可以正常工作,但在使用可更新的切换进行部署时,却编译失败。

  模型 ASP.NET 通常使用 App_Code 目录内容的单独程序集以及global.asax 文件(如果存在),然后将每个目录中的所有 .aspx页编译为单独的程序集。(如果同一目录中的页面是以不同语言制作的,或者它们通过 @ Reference指令彼此依赖,则它们也可以形成单独的程序集。)用户控件和母版页通常也独立于 .aspx 页进行编译。例如,如果要在一个项目中包含Visual Basic® 和 C# 源代码,也可以配置 App_Code目录来创建多个程序集。在程序集创建的细节中有一些细微差别,这取决于您所选的部署模式。 描述特定 Web 站点的组件,该 Web站点基于您要使用的部署模式编译为单独的程序集。(请注意,我要忽略资源、主题和浏览器目录,因为它们不包含代码,虽然它们也编译为单独的程序集。正如前面提到的,目标程序集也因语言的不同和引用依赖项而异。)

Deployment Mode
All Source All Binary Updatable (mixed)
What compiles into a unique assembly App_Code directory
global.asax
.ascx and associated codebehind file (separate assembly for eachuser control)
.master and associated codebehind file (separate assembly for eachmaster page)
All .aspx files and their code­behind files in agiven directory (separate assembly per directory) App_Codedirectory
global.asax
.ascx and .master files and their associated codebehind files
All .aspx files and their code­behind files in agiven directory (separate assembly per directory)App_Code directory (D)
global.asax (R)
.ascx and .master files (R)
codebehind files for .ascx and .master files (D)
All .aspx files in a given directory (separate assembly perdirectory) (R)
All codebehind files associated with .aspx files in a givendirectory (separate assembly per directory) (D)
When it's compiled Request time Deployment time (R) = Compiled atrequest time
(D) = Compiled at deployment time


  程序集生成的另一个技巧是,使用 aspnet_compiler 的-fixednames 选项请求将每个 .aspx文件编译为单独的程序集,该程序集的名称跨编译器的不同调用保持一致。如果您想更新单个页面而不修改部署站点上的其他程序集,这是很有用的。它也可以为任何大型站点生成大量程序集,因此您一定要在使用该选项之前测试您的部署。

  如果您觉得这比较复杂,我可以告诉您它的优点,即您无需花费大量时间考虑将哪些文件映射为单独的程序集。.aspx文件一直在最后进行编译,并一直包括对生成的所有其他程序集的引用,因此,无论您选择哪种部署模型,它通常都会正常工作。

  在部署中,可能实际影响您在页面中制作代码的方式的一个重要区别是,当使用可更新部署时编译中的分离。当部署可更新站点时,代码隐藏文件在部署之前编译为单独的程序集。从.aspx文件生成的类不进行编译,除非作出对目录中文件的实际请求。这与二进制部署(其中所有文件在部署之前编译)以及源部署(其中所有文件在请求时编译)形成了鲜明对比。以下这一简单的示例解释这是如何引出问题的,请考虑中带有嵌入属性的用户控件(.ascx文件),以及一个使用该控件并从其代码隐藏类设置该属性的相关页面。

MyUserControl.ascx

<%@ ControlLanguage="C#"%>
<script runat="server">
publicstring Color
{
get { return (string)ViewState["color"] ?? "white"; }
set { ViewState["color"] = value; }
}
protectedoverride void OnLoad(EventArgs e)
{
_mainPanel.BackColor = System.Drawing.Color.FromName(Color);
base.OnLoad(e);
}
</script>
<asp:Panel runat="server"ID="_mainPanel">
<h2>Sometext</h2>
Other text
</asp:Panel>

Default.aspx

<%@ Page Language="C#" CodeFile="Default.aspx.cs"Inherits="_Default" %>
codebehinde与codefile原理(转) codebehind
<%@ Register Src="MyUserControl.ascx"TagName="MyUserControl" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>UntitledPage</title>
</head>
<body>
<form id="form1"runat="server">
<div>
<uc1:MyUserControl id="MyUserControl1"runat="server">
</uc1:MyUserControl></div>
</form>
</body>
</html>

Default.aspx.cs

using System;
using System.Web.UI;
public partial class _Default : System.Web.UI.Page
{
protectedvoid Page_Load(object sender, EventArgs e)
{
MyUserControl1.Color = "purple";
}
}

  上面代码中的页面将以源或二进制部署模式编译并运行,但是当作为可更新站点部署时将无法编译,原因是该用户控件Color 属性的定义在部署时不可用(该限制也存在于 1.x模型中)。要避免此类问题发生,通常您可以将所有代码放在代码隐藏文件中,或者干脆不使用代码隐藏文件,将代码直接放在 .aspx 和.ascx 文件中。

  有关文件到程序集映射的另一个注意事项是,使用内部关键字防止外部程序集访问类中的方法,这可能只在某些部署方案中奏效而在其他方案中却不然,这是因为存在不同的程序集映射选项。除非您提前计划要使用哪个部署选项,否则最好避免在页面中使用内部方法并继续使用类型范围的保护关键字:公共、受保护和私有。

  小结

  对于 ASP.NET 开发人员而言,ASP.NET 2.0中的新代码隐藏模型既熟悉又陌生。之所以说熟悉是因为,它仍然使用继承将代码隐藏类与其 .aspx生成的类定义相关联,而之所以说陌生是因为,诸如部分类这样的元素和控件成员变量声明的隐式生成都是基本的转换。实际上,您可能不会注意到用法上的许多差别,但是无论您何时进行非一般的操作(例如,创建一个通用基Page 类,或者将代码隐藏与内联代码模型混合),了解本文描述的类关系和程序集映射都是很重要的。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mzphp/archive/2006/04/16/665204.aspx

  

爱华网本文地址 » http://www.aihuau.com/a/25101014/205496.html

更多阅读

尽职调查报告与法律意见书(转) 法律尽职调查报告

(转本文,不代表本人完全赞同作者的观点,仅表示该文具有交流意义)从事非诉法律业务的律师经常会写两个法律文件,一个是法律意见书、一个是尽职调查报告。但是在法律实务中如何使用这两份文件,这两份文件应当分别具备什么样的内容,在我省的

未来核动力飞船的工作原理转 核动力飞船可以飞多快

未来核动力飞船的工作原理(转)发表于:2010-08-06 21:33:23 作者:挣扎多年发短信加好友更多作品博客级别:少校      积分:13430主题推广:雾头山铁观音茶特价优惠中低价充话费,在返5元,秒充新茶上市铁观音直销大公开未来,当人们探索太阳

“做个信守承诺的人?”-承诺与一致原理 承诺与一致性原理

《影响力》书中说“承诺与一致”,是“脑子里的怪物”。现在我们觉察到了这个怪物,许多疑问就很好理解了。为什么会有“撞破南墙不回头”?当事人常见的说法是:“坚持就是胜利”,但是即使在看到很明显的信号表明坚持是错误的时候,他们还是一

潜水艇与鱼、飞艇与热气球原理的区别 热气球升空原理

2012-06-17 16:50:05|分类: 科研 |字号订阅潜水艇与鱼、飞艇与热气球的原理都是利用了物体的浮沉条件,但具体对浮沉条件的利用是有很大区别的。潜水艇与鱼鱼能够在水中随心所欲地游动,潜水艇能潜入水下自由航行,象鱼一样下沉、上浮和悬

声明:《codebehinde与codefile原理转 codebehind》为网友因为你所以青春分享!如侵犯到您的合法权益请联系我们删除