Asp.net button object - runat server issue

2020-07-14 05:51发布

问题:

I have a slight problem with creating a button on the server side code. I am using stringbuilder to build a table in html and I want to create a new button object and pass it into my stringbuilder object. The problem I have is my page doesn't compile when I am debugging. I want to give my button object a runat="server" property but I don't know how to.

Button add_img_popup = new Button();
            add_img_popup.Text = "Add new Image"; // text
            add_img_popup.Click += new EventHandler(addImgPopup_Click); // click event handler
            add_img_popup.Enabled = true;
            add_img_popup.ID = "btn_add_img_popup"; // programmatic id

            Page.Controls.Add(add_img_popup); // add to page controls so it renders

            st.Append("<tr>");
            st.Append("<td>");
            st.Append(add_img_popup); // pass to string builder
            st.Append("</tbody>");
            st.Append("</table>");

And the message the server gives me.


Server Error in '/' Application.

Control 'btn_add_img_popup' of type 'Button' must be placed inside a form tag with runat=server. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Control 'btn_add_img_popup' of type 'Button' must be placed inside a form tag with runat=server.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[HttpException (0x80004005): Control 'btn_add_img_popup' of type 'Button' must be placed inside a form tag with runat=server.] System.Web.UI.Page.VerifyRenderingInServerForm(Control control) +8702387 System.Web.UI.WebControls.Button.AddAttributesToRender(HtmlTextWriter writer) +54 System.Web.UI.WebControls.WebControl.RenderBeginTag(HtmlTextWriter writer) +20 System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +20 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99 System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +134 System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +19 System.Web.UI.Page.Render(HtmlTextWriter writer) +29 System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99 System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1266

回答1:

do not do this:

Page.Controls.Add(add_img_popup);

have a div with runat=server in your page inside the Form tag and if the div is called myDiv then do this:

myDiv.Controls.Add(add_img_popup);


回答2:

It looks like you might have a couple of problems here:

Missing form tag

Ensure that your page has a form tag with 'runat=server' specified.

<form id="form1" runat="server">
    <asp:PlaceHolder ID="ph1" runat="server"/>
</form>

Code Behind:

// Create the button control
Button add_img_popup = new Button();
add_img_popup.Text = "Add new Image";

// Add it the placeholder
// (which is inside the form)
ph1.Controls.Add(add_img_popup);

Button being added to stringbuilder

Adding a control to a stringbuilder will not cause it to be rendered. You will need to render the control into a string first, using something like this:

public string RenderControl(Control ctrl) 
{
    StringBuilder sb = new StringBuilder();
    StringWriter tw = new StringWriter(sb);
    HtmlTextWriter hw = new HtmlTextWriter(tw);

    ctrl.RenderControl(hw);
    return sb.ToString();
}

You can use the RenderControl method like this:

st.Append("<tr>");
st.Append("<td>");
st.Append(RenderControl(add_img_popup));
st.Append("</tbody>");
st.Append("</table>");

Although this will render the control, you may have some trouble handling the postback event (addImgPopup_Click) as the control must be recreated on each page load.

Why do you need to add the control to the StringBuilder rather than putting the control directly on the page? There are usually better ways of achieving a goal using existing ASP.NET controls, rather than rendering something to a string first.



回答3:

There is another way to go about doing this...

Put a <asp:button on the page, create a click event for it, and then mark it as hidden. Then when you build your table you just need to code in a normal html button with an OnClick event to fire the buttons callback...



回答4:

As the error says , you must put your button in a tag. so easily add it to your stream.