Control Attributes render Encoded on dot net 4 - h

2020-04-11 11:26发布

问题:

I have an issue in asp.net 4.

When I add an attribute on controls, then the render it encoded.

For example, when I type this code

txtQuestion.Attributes["onfocus"] = 
    "if(this.value == this.title)
{
   this.value = '';
   this.style.backgroundColor='#FEFDE0';
   this.style.color='#000000';
}";

I get render

onfocus="if(this.value == this.title){this.value = 
'';this.style.backgroundColor='#FEFDE0';
this.style.color='#000000';}"

And every ' hash been change to & #39;

Is there a way to disable this new future only on some controls ? or an easy way to make a custom render ?

My Fail tries

I have all ready try some thinks but I fail. For example this fails.

txtQuestion.RenderingCompatibility = new Version("3.5");

I also locate the point that this attributes renders and is on

public virtual void RenderBeginTag(HtmlTextWriterTag tagKey) function,

there every attribute have a flag if he wish to be encoded, but I do not know how can anyone set it or not.

One Work Around

In the asp net forum in the same question, there is a solution that change the global EncodeType - this is not the solution that I search for - and the person that give the solution say that this is not a great workaround, with potential security issues or other render issues.

Thank you all in advanced.

By Kervin

Until now Kervin found that Microsoft suggest instead use this command.

txtQuestion.Attributes["onfocus"] = 
    "if(this.value == this.title){this.value = '';this.style.backgroundColor='#FEFDE0';this.style.color='#000000';}";

Use this one.

    Page.ClientScript.RegisterExpandoAttribute(txtQuestion.ClientID, "onfocus", 
 "if(this.value == this.title){this.value = '';this.style.backgroundColor='#FEFDE0';this.style.color='#000000';}");

And what MS render, is on the end of the page, a script that add onfocus on this control using JavaScript. We can do that even by our self with jQuery and probably be more compatible.

This is a solution, but still I am wish to know if there is a way to just avoid the Attribute Encoding and let me do what I wish my way - not MS way.

回答1:

From MSDN WebControl.Attributes Property Documentation...

Note

You cannot add client-side script to a WebControl instance using the Attributes collection. To add client-side script, use the ClientScript property on the Page control.

The problem is that Attributes expects data if it's being set in the code-behind.

The solution is to send back a client script with your client side handler functions then you may set the attribute with the name of your functions.

If your javascript is static, then things are even simpler, since you can send them in a script tag long before the controls are registered.



回答2:

Have you tried using this new ASP.NET 4 feature to make a custom encoder?



回答3:

I ran into this problem with an MvcHtmlHelper for an autocomplete.

I ended up using |~| instead of ', and then replacing that with ' after Html.TextBox had rendered the string, but before we returned it.

That's a really annoying "security" feature.



回答4:

If you really want to prevent the encoding of parameters, you'll need to create your own customized control and override the AddAttributesToRender method. Obviously this isn't very flexible because you'll need to create a separate custom control for each type of control you use.

Fortunately, this is very easy and only needs a few lines of code so may work out. Here is the complete code needed for a customized button:

public class MyCustomButton : Button
{
    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
        base.AddAttributesToRender(writer);
        writer.AddAttribute("onclick", "myJavascriptFunction('a string');", false); // passing false to the AddAttribute method tells it not to encode this attribute.
    }
}

Obviously, this only appends a hard-coded onclick to the end of the attributes and may interfere if an onclick has already been provided. If you wanted to take this further, you could iterate over the actual Attributes collection and add them all this way.