使用Attributes.Add时,.Net 4.0会对单引号进行编码

11

.Net 4.0使用Attributes.Add为我的asp.net对象添加客户端事件时,会对单引号进行编码。在之前的版本中,这种情况并没有发生。

例如:

<asp:Image runat="server" ID="imgTest" ImageUrl="~/DateControl/cal.gif" />

 imgTest.Attributes.Add("onmouseover", "alert('Hello')");

当我查看客户端输出时,我得到的是

 <img id="ctl00_MainContent_calFromTimeStamp1_imgTest" onmouseover="alert(&#39;Hello&#39;)" src="../DateControl/cal.gif" style="border-width:0px;" />

我通过创建自定义编码器找到了一个解决方法:创建自定义编码例程,但我不想因为这个问题而停止整个网站的编码。有人有解决办法或者修复这个问题的想法吗?

6个回答

4
根据微软的说法,不应该使用WebControl.Attributes.Add()将JavaScript添加到HTML属性中,因为它会对属性值进行编码。

您不能使用Attributes集合向WebControl实例添加客户端脚本。要添加客户端脚本,请在Page控件上使用ClientScript属性。

来源

建议使用Page.ClientScript.RegisterExpandoAttribute(string controlId, string attributeName, string attributeValue, bool encode) 方法。在您的情况下,它应该是这样的:
Page.ClientScript.RegisterExpandoAttribute(
  imgTest.ClientID, 
  "onmouseover", 
  "alert('Hello')", 
  false /* Do not encode */
);

这将导致您页面中的一段JavaScript代码,该代码会在客户端设置属性。

3
客户端设置属性的JavaScript代码已经存在,但事件没有触发。我在Chrome和IE上尝试过。 - Hassan Mokdad
我也一样 - 我可以看到添加属性的脚本 - 但它没有触发。 - Ian

2

在.NET中设置事件属性的最佳方法是调用一个单一函数:

imgTest.Attributes("message") = "Hello";
imgTest.Attributes("onmouseover") = "showMessage(this);"

在你的页面或已注册脚本中:
function showMessage(ctrl) 
{
  alert(ctrl.getAttribute('message'));
}

你提供的示例并没有真正展示解决方案,因为你使用的文本中没有引号。考虑这个:link.Attributes["my_command"] = "myfunc('hello world')"; link.Attributes["onclick"] = "eval(this.my_command)";。新属性 my_command 确实被编码了,但是会被 eval() 方法解码。 - paul

0
感谢Franzo的链接,以下答案是复制并粘贴的:

您可以创建如下类来关闭属性编码:

public class HtmlAttributeEncodingNot : System.Web.Util.HttpEncoder
{
    protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
    {
        output.Write(value);
    }
}

并将此添加到web.config下面:
<httpRuntime encoderType="HtmlAttributeEncodingNot"/>

这给了我所需的控制权。 然而,现在我们必须担心新的控件可能依赖于新的标准4.0行为,并且不编码单引号,因此它仍然是不完美的,甚至更糟:安全性更差,因为我们不知道发生了什么,所以这真的不是一个很好的解决方法。 我认为只有微软可以正确地解决这个问题。其他人建议在这里需要一个HtmlAttributeString类:link 如果有这样一个类,并且Attributes.Add可以将这样的对象作为其值参数,则我们将再次拥有所需的控制权。

0

不建议关闭属性编码。如果您尝试默认防止编码,则未来会发生许多奇怪的行为,并且您必须为不良实践付出代价。

.NET始终对任何属性进行编码,以防止注入恶意脚本。因此,您应该遵循这种默认做法来保护您的程序。


0

imgTest.Attributes.Add("onmouseover", "alert(\'你好\')");


-3

在编程中,您可以在任何引号字符之前使用转义字符:

源代码:

this.Attributes.Add("onmouseover", string.Format("$(this).attr(\'src\',\'{0}\')",this.Page.ClientScript.GetWebResourceUrl(typeof(SwapImage), urlenabledkey)));

渲染:

onmouseover="$(this).attr('src','/WebResource.axd?d=kHY3FE9nMsUOvDU-pPthg4KQvVrnXlcASyA7dFf6L

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