C# – How to use the button tag with ASP.NET


I'd like to use the newer <button> tag in an ASP.NET website which, among other things, allows CSS-styled text and embedding a graphic inside the button. The asp:Button control renders as <input type="button">, is there any way to make a preexisting control render to <button>?

From what I've read there is an incompatibility with IE posting the button's markup instead of the value attribute when the button is located within a <form>, but in ASP.NET it will be using the onclick event to fire __doPostBack anyway, so I don't think that this would be a problem.

Are there any reasons why I shouldn't use this? If not, how would you go about supporting it with asp:Button, or a new server control based on it? I would prefer to not write my own server control if that can be avoided.

At first the <button runat="server"> solution worked, but I immediately ran into a situation where it needs to have a CommandName property, which the HtmlButton control doesn't have. It looks like I'm going to need to create a control inherited from Button after all.

What do I need to do in order to override the render method and make it render what I want?


DanHerbert's reply has made me interested in finding a solution to this again, so I've spent some more time working on it.

First, there's a far easier way of overloading the TagName:

public ModernButton() : base(HtmlTextWriterTag.Button)

The problem with Dan's solution as it stands is the innerhtml of the tag is placed into the value property, which causes a validation error on postback. A related problem is, even if you render the value property correctly, IE's braindead implementation of the <button> tag posts the innerhtml instead of the value anyway. So, any implementation of this needs to override the AddAttributesToRender method in order to correctly render the value property, and also provide some sort of workaround for IE so it doesn't completely screw up the postback.

The IE problem may be insurmountable if you want to take advantage of the CommandName/CommandArgument properties for a databound control. Hopefully someone can suggest a workaround for this.

I have made progress on the rendering:


This renders as a proper html <button> with the correct value, but it doesn't work with the ASP.Net PostBack system. I've written some of what I need to provide the Command event, but it doesn't fire.

When inspecting this button side-by-side with a regular asp:Button, they look the same other than the differences I need. So I'm not sure how ASP.Net is wiring up the Command event in this case.

An additional problem is, nested server controls aren't rendered (as you can see with the ParseChildren(false) attribute). It's pretty easy to inject literal html text into the control during render, but how do you allow support for nested server controls?

Best Answer

Although you say that using the [button runat="server"] is not a good enough solution it is important to mention it - a lot of .NET programmers are afraid of using the "native" HTML tags...


<button id="btnSubmit" runat="server" class="myButton" 

This usually works perfectly fine and everybody is happy in my team.