在我的ASP.net代码中使用JavaScript代码作为字符串文字有一个很好的替代方案吗?

时间:2010-09-14 21:24:00

标签: javascript asp.net

在ASP.net Web应用程序上工作,我一直想知道是否有一种很好的方法可以避免在我的ASP.net代码中用字符串文字编写JavaScript代码。见这里:http://www.4guysfromrolla.com/articles/030202-1.aspx

在链接的示例中,我看到的代码如下:

Private Sub Calendar1_SelectionChanged(sender As Object, e As EventArgs)
  Dim strjscript as string = "<script language=""javascript"">"
  strjscript &= "window.opener." & _
        Httpcontext.Current.Request.Querystring("formname") & ".value = '" & _
        Calendar1.SelectedDate & "';window.close();"
  strjscript = strjscript & "</script" & ">" 'Don't Ask, Tool Bug

  Literal1.Text = strjscript  'Set the literal control's text to the JScript code
End Sub

我不习惯使用很多JavaScript。我使用的很多代码主要是使用T-SQL进行服务器端编码。上面的代码让我头疼只是看着它。它不仅难看,而且还显示出恶意用户可能会尝试注入恶意代码的模式。

有没有更好的方法可以避免将JavaScript代码作为字符串文字进行操作?想想我们必须避免将T-SQL代码作为字符串文字进行操作的方法。

8 个答案:

答案 0 :(得分:1)

一种常见的方法是使用clientscriptmanager类:

http://msdn.microsoft.com/en-us/library/z9h4dk8y.aspx

您可以调用registerstartupscript方法,该方法将脚本添加到页面的末尾,在页面完成加载时但在页面的OnLoad事件被引发之前执行。

RegisterClientScriptBlock方法将脚本添加到页面顶部。这是您可以添加常用功能的地方。

  Dim script As New StringBuilder()
  script.AppendFormat("window.opener.{0}", Httpcontext.Current.Request.Querystring("formname"))
  script.AppendFormat(".value = '{0}';window.close();", Calendar1.SelectedDate)

  Dim cs As ClientScriptManager = Page.ClientScript
  cs.RegisterClientScriptBlock(Me.GetType(), "ScriptKey", script.ToString(), true)

最后一个参数告诉脚本管理器将脚本包装在<script>...</script>标签中,这样您就不必这样做了。

此外,如果要从用户控件添加脚本,“ScriptKey”会确保不会多次添加相同的脚本。如果每个控件都需要单独的脚本,则可以根据控件ID动态生成该参数。

在页面上添加指向脚本文件的链接的另一种常用方法是RegisterClientScriptInclude

答案 1 :(得分:1)

呃,动态构建javascript并将其放入文字中?

通常我在代码中嵌入javascript的唯一一次是当我制作一个自定义控件并希望它整齐地打包(没有sepatate js文件需要担心),甚至那时我使用RegisterClientScriptBlock而不是像这样的hack。

为什么不在页面源(或包含文件)中有一个javascript函数,它接受两个参数(表单名称和选定日期),然后动态构建函数调用而不是整个脚本?

答案 2 :(得分:1)

不是写出完整的函数,而是将函数嵌入页面或外部文件中,只动态写出值。例如:

<script>
   <asp:Literal ID="ScriptValues" runat="server" />
</script>

<script>
     function foo(bar) { ... }
</script>

然后在你的代码后面或任何地方(对不起,我不做VB):

var values = new StringBuilder();
values.Append("var bar = " + bar + ";");
...
ScriptValues.Text = values.ToString();

答案 3 :(得分:0)

对于初学者来说,StringBuilder比使用String要好得多(它更容易阅读和更多性能调整)

Dim sbuild As StringBuilder = New StringBuilder
sbuild.Append("<script language=""javascript"">")
sbuild.Append("window.opener.")
sbuild.Append(Httpcontext.Current.Request.Querystring("formname"))
sbuild.Append(".value = ")
sbuild.Append(Calendar1.SelectedDate)
sbuild.Append("';window.close();")
sbuild.Append("</script>")

Literal1.Text = sbuild.ToString

但除此之外,我建议尝试像TagBuilder类这样的东西。它说它适用于MVC,但我不明白为什么你也不能在Web Forms场景中使用它(你只需要导入MVC命名空间) - (尽管我在这部分可能是错的)。

答案 4 :(得分:0)

在处理您的问题时需要考虑一些事项。

有几种方法,包括Page.RegisterClientScript,可以处理一些脏工作,通过将JavaScript代码正确包装在适当的标记中,以及将其放在页面中的适当位置(内联与开头/结束)将处理一些格式问题。

上面的代码示例是VB.Net,由于需要将&amp; _附加到每一行,因此需要处理大量文本。 C#在这方面做得更好。好消息是,随着.Net 4的发布,你不再需要担心所有的行连接。

如果您要处理需要嵌入的大量文本,可以考虑将JavaScript保存在单独的文本文件中,并将文件读入文字或脚本注册。如果必须有一些动态数据,你甚至可以做一些简单的字符串替换。 StringBuilder类也是一个帮助,使用了Append和AppenLine方法(),但它又取决于你要处理的文本数量以及你需要使用相关代码块的频率。

答案 5 :(得分:0)

从rockinthesixstring发布的示例中,如果你想“清理”代码的视觉方面,你也可以把它写成:

Dim sbuild As StringBuilder = New StringBuilder
With sbuild
   .Append("<script language=""javascript"">")
   .Append("window.opener.")
   .Append(Httpcontext.Current.Request.Querystring("formname"))
   .Append(".value = ")
   .Append(Calendar1.SelectedDate)
   .Append("';window.close();")
   .Append("</script>")
End With

Literal1.Text = sbuild.ToString

但是我会研究方法Page.ClientScript

Page.ClientScript.RegisterStartupScript  

或者如果您使用ScriptManager

ScriptManager.RegisterStartupScript

答案 6 :(得分:0)

尽可能多地移动到.js文件中。

如果有的话,你应该只需要渲染简单的js函数调用。我尝试通过添加一个css类然后使用jquery的类选择器来附加行为来最小化对这些的需要。

答案 7 :(得分:0)

在ASP.NET中使用JavaScript时,这些是您应该遵循的路径:

将其放在单独的JavaScript文件中。更多可维护的。

但是,如果您(无论出于何种原因)无法将其放在JavaScript文件中,请将其放在静态类中,该类将脚本公开为带有占位符的常量以插入值(使用@符号,这样您就没有了逃避角色。

像这样:

public static class JavaScriptStuff
{
    public const string SpecialScriptFormat = @"window.opener.{0}.value = '{1}';window.close();"
}

然后使用ClientScriptManager注册它 - 这样你也不需要明确打开/关闭脚本标记(停止人为错误)。

http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.aspx

string myScript = string.Format(JavaScriptStuff.SpecialScriptFormat, HttpContext.Current.Request.QueryString("formname"), Calendar1.SelectedDate);
Page.ClientScript.RegisterStartupScript(this.GetType(), "myscript", myScript, true);

你可以更进一步,不要将脚本公开为公共属性,而是公开接受params的“getter”方法 - 这增加了另一层可维护性:

public static class JavaScriptStuff
{
        private const string SpecialScriptFormat = @"window.opener.{0}.value = '{1}';window.close();"

        public string GetSpecialScript(string queryString, string selectedDate)
        {
           return string.Format(SpecialScriptFormat, queryString, selectedDate);
        }
    }
}

Page.ClientScript.RegisterStartupScript(this.GetType(), "myscript", JavaScriptStuff.GetSpecialScript(HttpContext.Current.Request.QueryString("formname"), Calendar1.SelectedDate), true);

HTH