【问题标题】:ASP.NET inline server tagsASP.NET 内联服务器标记
【发布时间】:2011-01-07 15:20:12
【问题描述】:

我想首先说我的代码运行良好,这更像是一个“如何最好地做到这一点”的问题。

所以我的.aspx 文件中有这样的代码:

    function EditRelationship() {
        var projects=<%= GetProjectsForEditRelationship() %>;

        // fill in the projects list
        $('#erProjectsSelect').empty();
        for(var i in projects)
            $('#erProjectsSelect').append('<option value='+projects[i][0]+'>'+projects[i][1]+'</option>');

        var rels=<%= GetRelationshipsForEditRelationship() %>;

        // etc
    }

再次,它工作正常。问题是 VS2008 在这样的代码上有点窒息,它在标签中强调 &lt; 字符(带有相关警告),然后拒绝为其余的 javascript 提供代码完成。 它也拒绝再格式化我的文档,导致解析错误。最后一部分是我最大的烦恼。

我猜我可以将其中的一些放在evals 中,但是添加额外的层和运行时性能命中只是为了关闭 VS 似乎有点愚蠢,而且它并不总是一个选项(我不记得在我的脑海中,这不是一个选择,但相信我,我有一个奇怪的结构)。

所以我的问题是,你如何最好地写这个(最好意味着最少的 VS 投诉)? eval 和 ajax 调用都不适合这个 imo。

【问题讨论】:

  • 我猜 GetProjectsForEditRelationship()GetRelationshipsForEditRelationship() 返回逗号分隔的字符串或数组?
  • 是的,基本上是 JSON 数据,所以eval 和 ajax 调用都可以。我只是不想要这样一点好处的开销。我很确定我会坚持这一点,但问起来永远不会有坏处!
  • 附加引号,因为它是一个变量,例如var projects='&lt;%= GetProjectsForEditRelationship() %&gt;'; - 我一直在使用它,VS2008 和 2010 并没有说它是错误的,并且一直给我智能感知。
  • 附带说明,projects[i][1] 是用户可编辑的值吗?如果是这样,您可能有 XSS 漏洞:)
  • @Blindy 顺便说一句,我认为始终尝试在性能和编写方式优雅的代码之间取得平衡非常重要。很高兴看到你有同样的想法。我现在正在一个网站上工作,其中每一行都是 response.write,因此您甚至无法在设计器中查看页面。不是我需要;)

标签: javascript asp.net servertag


【解决方案1】:

如果您的目标是减少 VS 投诉,并且如果您正在运行 asp.net 4(支持静态客户端 Id),也许像以下这样的策略会更好?

  1. 创建一个 ASP:HiddenField 控件,将其 ClientIdMode 设置为“静态”
  2. 在页面加载时将 GetRelationshipsForEditRelationship() 的值分配给该字段
  3. 在您的 javascript 中,改为从隐藏字段中读取值,我假设您知道如何执行此操作。

这比您的解决方案工作量更大,您将在回发中添加一些数据(如果您执行任何操作),但我猜它不会引起任何 VS 投诉 :)

【讨论】:

  • 嗯,我刚看到 Hunter 的回答……可能比我的要好得多:)
  • 可以跳过2,我可以像&lt;asp:HiddenField Value="&lt;%= ... %&gt;"... /&gt;一样分配它的值。有趣的想法!
  • 不要把你的想法卖得太短,我喜欢数组声明在同一个代码页中的事实,并且很清楚如何找到它(而不是在代码后面按名称搜索声明)。
【解决方案2】:

您可以在代码隐藏的页面中执行此操作

ClientScript.RegisterArrayDeclaration("projects", "1, 2, 3, 4");

或者构建类似 JSON 的东西,你可以把它写出来

ClientScript.RegisterClientScriptBlock(GetType(), "JSONDeclarations", "your json stuff");

更新基于我的评论

<script id="declaration" type="text/javascript">
    var projects=<%= GetProjectsForEditRelationship() %>;
    var rels=<%= GetRelationshipsForEditRelationship() %>;
</script>
<script type="text/javascript">
    function EditRelationship() {
        // fill in the projects list
        $('#erProjectsSelect').empty();
        for(var i in projects)
            $('#erProjectsSelect').append('<option value='+projects[i][0]+'>'+projects[i][1]+'</option>');
}
</script>

【讨论】:

  • 嗯,也许吧,虽然这会使代码不那么清晰(您必须在后面的代码中搜索数组名称才能看到其中的内容),而且您正在污染内部的全局命名空间。但请务必牢记这一点。
  • 好吧,如果目标是保持智能感知,我不知道你有什么选择,因为内联服务器标签会炸毁它。也许您可以使用 2 个&lt;script&gt; 块?一个用于定义 JSON 值,一个用于您的代码?这可能不会炸毁智能感知
  • 值得一试。渲染服务器标签应该炸毁js智能感知,因为就它而言,它是无效的。
  • 如果你这么说。在我看来,标记引擎应该意识到它是一个服务器标签并将其视为服务器标签。他们已经为实际的 ASP 标签做到了这一点,那么为什么 JavaScript 也不行呢?
【解决方案3】:

我没有安装 VS2008 来进行测试,所以对它持保留态度,但你尝试过这样的事情吗?

var projects = (<%= GetProjectsForEditRelationship() %>);

这样的事情可能会诱使 JavaScript 解析器忽略表达式的内容。

对于它的价值,VS2010 正确解析并突出显示您的原始代码 sn-p。

【讨论】:

  • 我同意@Dave。我刚刚复制并粘贴了您的代码,IDE 正确解释了它。
  • 哇,我对这个寄予厚望,但没有骰子:(
  • @Doug,在 VS2008 中?我刚刚在另一段代码上再次尝试,它仍然给我它的警告。
【解决方案4】:

是否可以将其移至 VS2010?我刚刚复制并粘贴了您的代码,IDE 正确解释了它。

【讨论】:

  • 我认为它会,我们最终会迁移到 vs2010,但这还不是一个选择:(
【解决方案5】:

最好的解决方案是将 javascript 放在一个单独的文件中并完全避免这种情况。对于这个特定的功能,您正在做服务器端的工作。为什么不构建您打算在代码隐藏中动态添加的选项列表,将它们放在隐藏的 div 中,然后让 jQuery 从已经渲染的 HTML 中添加它们?

如果您确实想以这种方式动态创建大量 javascript,请考虑在代码隐藏中使用 ScriptManager 将您需要的变量设置为脚本并注册它们,那么您的内联脚本就不需要逃跑

ScriptManager.RegisterClientScript("projects = " + GetProductsForEditRelationship());

(基本上,这不是完整的语法,它取决于上下文)。然后在你的函数中引用“项目”。

(编辑)

在更大规模的情况下执行此操作的更简洁的方法,在代码隐藏中设置您需要的所有内容:

string script = "var servervars = {" +
  "GetProductsForEditRelationship: " + GetProductsForEditRelationship() + 
  "GetRelationshipsForEditRelationship: " + GetRelationshipsForEditRelationship() +
"}"

并参考以下所有内容:

servervars.GetProductsForEditRelationship

如果你经常这样做,当然,你可以创建一个类来自动构建脚本。

【讨论】:

  • 我没有给你-1,但你的(第二个)想法与猎人的答案没有任何不同。同样的难以发现的问题,即数组是一目了然的问题:)
  • 反正我的脸皮很厚 :) 您可以使用避免这种情况的约定,例如只需调用与函数同名的 js 变量或类似 cbfunc_GetProductsForEditRelationship 的名称。我在这种情况下使用的一个更好的解决方案是创建一个 js 对象,该对象包含您在关联 js 中使用的所有内容,并在代码隐藏中构建它(在一秒钟内编辑)
  • Erm.. 可能是早上太早了,但是 VS 不会抱怨代码中的内联服务器标签吗?这就是我首先要避免的。
  • 一旦您消除了转义到内联代码的需要,通过提前将所有内容作为 javascript 变量提供,您就没有任何理由将其直接包含在标记中。放到VS不会报错的JS文件中。
  • 我删除了该编辑的命名容器部分。抱歉,现在是凌晨。我试图抽象地描述我实际实现的东西。为了使其与控件的多个实例一起工作(例如)并命名容器安全,您必须设置所有函数以接受作为参数动态创建的 javascript 对象。可能在这里很远。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
  • 2012-01-22
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多