Search code examples
c#asp.netwebformsregisterstartupscript

Strange conflict between get postback control and RegisterStartupScript


Please consider this scenario:

I have a simple page and I want to log all controls causing postback. I create this simple page. It contains a grid to show some URLs and when user click on an icon a new tab should open:

enter image description here

<form id="form1" runat="server">
<div>
        <table style="width: 100%;">
            <tr>
                <td style="background-color: #b7ffbb; text-align: center;" colspan="2">
                    <asp:Button ID="Button3" runat="server" Text="Click Me First" Height="55px" OnClick="Button3_Click" />
                </td>
            </tr>
            <tr>
                <td style="background-color: #f1d8fe; text-align: center;" colspan="2">
                    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" BackColor="White" OnRowCommand="GridView1_RowCommand">
                        <Columns>
                            <asp:BoundField DataField="SiteAddress" HeaderText="Address" />
                            <asp:TemplateField>
                                <ItemTemplate>
                                    <asp:ImageButton ID="ImageButton1" ImageUrl="~/download.png" runat="server" CommandArgument='<%# Eval("SiteAddress") %>' CommandName="GoTo" Height="32px" Width="32px" />
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>
                </td>
            </tr>
        </table>
    </div>
</form>

and code behind:

public partial class WebForm2 : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Button3_Click(object sender, EventArgs e)
    {
        List<Address> Addresses = new List<Address>()
        {
            new Address(){ SiteAddress = "https://google.com" },
            new Address(){ SiteAddress = "https://yahoo.com" },
            new Address(){ SiteAddress = "https://stackoverflow.com" },
            new Address(){ SiteAddress = "https://learn.microsoft.com/}" }
        };

        GridView1.DataSource = Addresses;
        GridView1.DataBind();
    }

    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        ScriptManager.RegisterStartupScript(this, this.GetType(), "MyScript", "window.open('" + e.CommandArgument.ToString() + "', '_blank')", true);
    }
}

class Address
{
    public string SiteAddress { get; set; }
}

every thing is fine till here. Now I create a base class for all of my pages and add below codes for finding postback control:

public class MyPageBaseClass : Page
{
    protected override void OnInit(EventArgs e)
    {
        if (!IsPostBack)
        {
            
        }
        else
        {
            var ControlId = GetPostBackControlName();   <------
            //Log ControlId 
        }
        base.OnInit(e);
    }

    private string GetPostBackControlName()
    {
        Control control = null;

        string ctrlname = Page.Request.Params["__EVENTTARGET"];
        if (ctrlname != null && ctrlname != String.Empty)
        {
            control = Page.FindControl(ctrlname);
        }

        else
        {
            foreach (string ctl in Page.Request.Form)
            {
                Control c;
                if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
                {
                    string ctrlStr = ctl.Substring(0, ctl.Length - 2);
                    c = Page.FindControl(ctrlStr);
                }
                else
                {
                    c = Page.FindControl(ctl);
                }
                if (c is System.Web.UI.WebControls.Button ||
                         c is System.Web.UI.WebControls.ImageButton)
                {
                    control = c;
                    break;
                }
            }

        }

        if (control != null)
            return control.ID;
        else
            return string.Empty;
    }
}

and change this line:

public partial class WebForm2 : MyPageBaseClass

Now when I click on icons grid view disappears...(STRANGE...) and nothing happened. When I comment specified line then every thing will be fine...(STRANGE...).

In GetPostBackControlName nothings changed to Request but I don't know why this happened. I checked and I see if I haven't RegisterStartupScript in click event every thing is fine. Please help we to solve this problem. Thanks


Solution

  • The problem is related to OnInit event. I replaced it with OnPreLoad and every things is fine now.

    For search engines: OnInit event has conflict with RegisterStartupScript