我正在使用 ASP.NET MVC2 和 C#,但这个问题通常适用于 ASP.NET。
这打破了:
<body id="<asp:ContentPlaceHolder ID="BodyID' runat="server" />">
Intellisense 在body
之后立即在标签和开头引号下划线id=
,并抱怨:
验证 (HTML 4.01):元素 'body' 缺少其开始标记中的 '>' 字符。
asp 元素被忽略,渲染的 HTML 中的 id 属性为空。(无论我在 ASP 元素中使用双引号还是单引号,都会出现同样的问题,但后者会破坏 VS 中的语法高亮显示。)
这有效(假设我设置了会话变量):
<body id="<%: Session["BodyID"] %>">
为什么 HTML 属性内支持内联求值,但 ASP 控件不会在属性内呈现?
这是我的用例:根据从控制器传递的数据,视图知道它正在呈现什么类型的数据。视图将数据注入到母版页的各个位置。我可以将标题注入头部,将标记注入正文——但我也想将数据注入一些属性。ID 和类名是明显的例子,但还有其他例子。
我想在保持有效标记的同时做到这一点;没有像动态呈现整个 body 标记这样的技巧——我想要一个在 Visual Studio 中始终看起来像有效 HTML 或 XML 文档的页面。
使用内联评估是可以的,但它需要我设置属性,我在模型或控制器中执行此操作。在某些情况下这是必要的,但在其他情况下,值是静态的——我有一个专门构建的视图,我只需将视图中的静态值注入母版页。我不想通过创建抽象控制器类的所有开销,让我的所有控制器都从它继承等等,只是为了获得我在注入标记时已经拥有的相同功能。
附带问题(是的,我应该为此打开一个单独的问题):ASP 控件和内联代码块的评估顺序是什么?我假设代码块在 ASP 控件之前首先被解析,所以我可以例如将代码块放在 ASP 控件声明中。但是我找不到详细说明该过程的文档 - 任何人都可以向我指出它们吗?
谢谢!
更新: Pauli 提到您确实可以在任何您喜欢的地方使用 ContentPlaceholders,只要它们不在已标记的元素内runat="server"
。我再次测试,发现他是正确的——我最初错过了。Visual Studio 仍然一头雾水,并给出了 HTML 验证警告,但在呈现页面时,预期值会出现在属性中。所以,这个问题的答案是“但你可以!”