为什么我不能在ASP.NET的HTML属性中使用ContentPlaceholder?

3
我是ASP.NET MVC2和C#开发者,但是这个问题适用于ASP.NET的所有版本。
以下代码出现错误:
<body id="<asp:ContentPlaceHolder ID="BodyID' runat="server" />">

智能感知在body标签和id=后的开头引号下划线,并抱怨:

验证(HTML 4.01):元素“body”缺少其开始标记中的“>”字符。

渲染的HTML中忽略了asp元素,并且id属性为空。(无论我在ASP元素内使用双引号还是单引号,都会出现相同的问题,尽管后者会破坏VS中的语法突出显示。)
这个可以工作(假设我设置了会话变量):
<body id="<%: Session["BodyID"] %>">

为什么HTML属性内支持内联计算,但ASP控件不能渲染到属性中呢?
以下是我的用例:基于从控制器传递的数据,视图知道它正在渲染的数据类型。视图将数据注入主模板的各个位置。我可以将标题注入到中,并将标记注入到中 - 但我还想将数据注入到某些属性中。ID和类名是明显的示例,但还有其他情况。
我希望在保持有效标记的同时做到这一点;没有像动态渲染整个标签这样的技巧 - 我希望在Visual Studio中始终看起来像是一个有效的HTML或XML文档。
使用内联eval是可以的,但需要设置属性,在模型或控制器中进行设置。在某些情况下这是必要的,但在其他情况下值是静态的 - 我有一个特定用途的视图,我只需要将视图中的静态值注入到主页面中。我不想通过创建抽象控制器类、让所有控制器都继承自它等方式来获取已经拥有的相同功能,而需要经历所有的额外开销。
附属问题(是的,我应该为它打开一个单独的问题):ASP控件和内联代码块的评估顺序是什么?我假设在ASP控件之前解析代码块,因此我可以将代码块放置在ASP控件声明内部。但我找不到详细描述这个过程的文档 - 有人能向我指出吗?
谢谢!
更新:Pauli提到你确实可以在任何地方使用ContentPlaceholders,只要它们不在已标记为runat="server"的元素内部即可。我进行了测试,看到他是正确的 - 我最初错过了这一点。Visual Studio仍然混淆并给出HTML验证警告,但在呈现页面时,预期值会出现在属性中。因此,回答这个问题是“但你可以!”

占位符对于仅需属性值来说可能过分了。 - Guillaume86
这种传输数据到主页面的技术并不像我看到的其他技术那样过度!例如,参见https://dev59.com/HnVD5IYBdhLWcg3wHn6d 我认为我只是想从视图获取一个ID到主页面?;-) - Val
1个回答

2
  1. 在MVC中不应该使用WebForms控件
  2. 在ID和runat周围使用'',因为解析器会混淆所有冲突的""

由于body标签没有runat="server",它不被视为服务器控件,而只是清晰的文本,因此您可以在任何地方放置contentplaceholder或其他控件。


1
ContentPlaceHolders在MVC中完全没有问题。它们在随附MVC的示例项目中也有使用。 - Jack Marchetti
我说过你不应该... 当然,使用asp:repeater、asp:calendar等也完全没问题,但在MVC中呈现内容时,我建议坚持使用HtmlHelpers。 - Pauli Østerø
是的,但是HTMLHelper在这里对我没有帮助——需要数据的是主页面,但是帮助程序将位于视图上。无论我如何生成内容,我只能通过两种方式之一将其注入到主页面中:ContentPlaceholder或内联eval调用函数或属性。 - Val
Pauli,在另一个答案中,你指出将控件放置在属性内确实可行,我现在看到这是正确的。如果您创建一个单独的回答来表明这一点,我会接受它。 - Val

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