为什么ASP.NET WebForms需要Runat="Server"属性?

209

当我在ASP.NET控件上指定“runat =“server””属性时,这是一个强制性的属性,而且在我有限的ASP.NET知识中,“server”是唯一可用的选项,如果我不使用它会出错,为什么要这样做呢?

我知道在HTML标记上可以选择性地使用它,我也知道客户端/服务器范例以及它实际指定的内容。

这个属性是否是多余的,可以通过控件本身是ASP.NET控件来隐含,还是有潜在的原因?


2
我同意这个问题,进一步澄清一下,'asp:'(以及您在标头中指定的其他标记)不足以进行解析吗?还是说runat在控件转换为INPUT后被触发,因此与其他HTML无法区分?我认为runat应该在它仍处于服务器控件形式时被触发... - abend
1
也许在 Web.config 中添加一种“默认属性”配置选项,可以基于前缀或名称,这可能是一个合适的解决方法。在解析过程中,必要时可以将默认属性注入到 DOM 中。我会尝试实现这个想法... - Dan Lugg
14个回答

113
我一直认为,更多的是为了理解ASP.NET标记和HTML标记可以混合使用,而HTML标记可以选择是否runat="server"。保留标记不会有任何影响,将其删除会导致编译器错误。对于想学习网页语言的新手程序员来说,暗示的东西越多,学习就越困难。这是详细说明标记属性的充分理由。
这段对话发生在Mike Schinkel的Blog上,他与Microsoft National Services的Talbot Crowell进行了交流。以下是相关信息(第一段由于来源中的语法错误进行了改写):

[...]<runat="server">的重要性更多体现在一致性和可扩展性方面。

如果开发人员必须标记某些标记(即<asp: />),以便ASP.NET引擎忽略它们,则还存在标记命名空间冲突和未来增强的潜在问题。通过要求<runat="server">属性,可以消除这种情况。

然后是这样的:

如果所有客户端标记都需要<runat=client>,则解析器需要解析所有标记并剥离<runat=client>部分。

他继续说:
当前,如果我猜测正确的话,解析器只会忽略所有的文本(包括标签和非标签),除非它是带有runat=server属性的标签,或者是以“<%”前缀或ssi“<!– #include…”开头的文本。另外,由于ASP.NET旨在允许网页设计人员(foo.aspx)与网页开发人员(foo.aspx.vb)分离,因此网页设计人员可以使用自己的网页设计工具来放置HTML和客户端JavaScript,而无需了解ASP.NET特定的标签或属性。

59
无论原因是什么,每次在asp:标记中输入它仍然很麻烦,而它本来可以安全地成为默认值。 - belugabob

33

我通常不喜欢猜测,但这一次我要猜一下...

如果你还记得微软在过去(2001年?)关于.NET的营销炒作,那么很难确定.NET到底是什么。它是一个服务器吗?编程平台?语言?还是全新的东西?根据广告,它可以是你想要的任何东西——它只是解决你可能遇到的任何问题。

所以,我的猜想是有一个隐藏的宏伟愿景,即ASP.NET代码可以在任何地方运行——服务器端或客户端,在与.NET运行时绑定的Internet Explorer副本中。runat="server"只是一个残留的痕迹,因为它的客户端等效部分从未进入生产。

还记得那些奇怪的广告吗?

相关:The Register上的一篇.NET历史文章


5
你有没有奇怪广告的网站链接? - RandomWebGuy
是的,我确实记得那些奇怪的广告。叹气 - catfood

13

并非所有可以包含在页面中的控件必须在服务器上运行。例如:

<INPUT type="submit" runat=server />

这基本上与以下内容相同:

<asp:Button runat=server />

从第一个标签中删除runat = server标记,您将获得在浏览器中运行的标准HTML按钮。关于在服务器上运行特定控件的理由利弊各有千秋,并且ASP.NET无法根据您包含的HTML标记“假定”您想要什么。可能可以为<asp:XXX />控件系列“推断”runat = server,但我猜Microsoft会认为这是对标记语法和ASP.NET引擎的篡改。


2
如果控件在服务器上运行,那么是否意味着您无法使用Javascript选择元素?例如:document.getElementsById("tvns:treeview"); - Ciaran Gallagher
3
元素仍将存在于客户端的DOM中,因此仍然可以使用JavaScript / jQuery进行修改。 但是,与服务器呈现的元素一起工作可能会很棘手,特别是对于动态控件而言。 - Dave Swersky

9

微软 MSDN 文章 《遗忘的控件:HTML 服务器控件》 解释了如何使用带有一个文本框 <input type="text"> 的示例来演示在 HTML 元素上添加 runat="server"

这样做将使您在 Web 页面创建并发送到客户端之前,在服务器上对 HTML 元素进行编程访问。HTML 元素必须包含一个 id 属性,该属性用于标识元素,并使您可以按其特定 ID 编程到元素。除此属性外,HTML 元素还必须包含 runat="server"。这告诉处理服务器,该标签在服务器上处理,不应视为传统的 HTML 元素。

简而言之,要实现程序化访问 HTML 元素,请将 runat="server" 添加到它。


2
不回答问题,问题是为什么在ASP.NET标记上必须使用runat="server"。 - nhahtdh
3
答案是:“使HTML元素可编程访问”。 :) - Developer Marius Žilėnas
2
OP知道标签的含义和作用。问题是在语言设计方面提出的 - 是什么让设计者决定即使是ASP.NET标签也需要使用runat =“server”标记才能在服务器端运行。 - nhahtdh
@nhahtdh 你的答案是什么? - Developer Marius Žilėnas
2
我没有答案,但是顶部的答案回答了这个问题(正确与否)。你的答案没有回答问题,这就是我评论的原因。 - nhahtdh

3
我怀疑这与服务器端控件在处理期间如何被识别有关。它不必通过名称在运行时检查每个控件以确定是否需要进行服务器端处理,而是通过标签在内部节点表示中进行选择。编译器在验证步骤中检查所有需要服务器标记的控件是否具有它们。

2

ASP.NET文件中的HTML元素默认被视为文本。要使这些元素可编程,需要在HTML元素中添加runat="server"属性。此属性表示该元素应被视为服务器控件。


1
如果您在普通的html标签上使用它,意味着您可以在事件处理程序中通过编程地操作它们,例如在页面加载时更改锚定标记的href或class...只有在必要时才这样做,因为原始的html标签会更快。
就用户控件和服务器控件而言,没有,没有它们就不能工作,如果没有深入了解aspx预处理器的内部细节,无法确切地说出为什么,但猜测可能是出于某种好的原因,他们只是按照明确标记为“执行某些操作”的方式编写解析器。
如果@JonSkeet在附近的话,他可能能够提供更好的答案。

1

这是因为在ASP .NET中,所有控件都继承自System.Web.UI.Control,该控件具有“runat”属性。

在System.Web.UI.HTMLControl类中,该属性不是必需的,但在System.Web.UI.WebControl类中,该属性是必需的。

编辑: 让我更具体一些。由于asp.net基本上是HTML的抽象,编译器需要某种指令,以便它知道特定的标记需要在服务器端运行。如果没有该属性,则不会知道首先在服务器上处理它。如果没有它,它会假设它是常规标记,并将其传递给客户端。


3
你的答案实际上就是同一个问题的重述。 - Pablo Fernandez
2
我的回答只是简单地说明了runat属性存在的原因是继承。非常抱歉我没有表达清楚。 - Russ Bradberry
3
恐怕我的问题有点太深奥了,我想知道的是为什么它一开始就在那里。不管怎样,还是谢谢您。 - johnc
2
再次强调,我并没有正面回答你的问题,但我理解你想要表达什么。 - johnc

1

我认为微软可以通过让编译器在编译页面之前添加runat属性来解决这种歧义,就像Java中的泛型擦除一样,它可以在看到asp:标签前缀时写入runat=server,而不是擦除,这样开发人员就不需要担心了。


0
相当冗余的属性,考虑到 "asp" 标签显然是一个 ASP 元素,并且应该足以将其标识为服务器端可访问元素。
但在其他地方,它被用来将普通标记提升为可在代码后台中使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接