获取回发控制和 RegisterStartupScript 之间的奇怪冲突
Strange conflict between get postback control and RegisterStartupScript
请考虑这种情况:
我有一个简单的页面,我想记录导致回发的所有控件。我创建了这个简单的页面。它包含一个网格来显示一些 URL,当用户点击一个图标时,一个新的标签应该打开:
<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>
和后面的代码:
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://whosebug.com" },
new Address(){ SiteAddress = "https://docs.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; }
}
到这里一切都很好。现在我为我的所有页面创建一个基础 class 并添加以下代码以查找回发控件:
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;
}
}
并更改此行:
public partial class WebForm2 : MyPageBaseClass
现在,当我单击图标时,网格视图消失了...(奇怪...)并且没有任何反应。当我评论指定行时,一切都会好起来的...(STRANGE...).
在 GetPostBackControlName
中什么都没有更改为 Request
但我不知道为什么会这样。我检查了一下,看看我是否没有在点击事件中 RegisterStartupScript
一切都很好。请帮助我们解决这个问题。
谢谢
when I click on icons grid view disappears...
ASP.Net 页面 class 对象实例的寿命仅够服务一个 HTTP 请求,默认情况下每个 HTTP 请求都会重建整个页面。
每次执行回发时,您都会有一个新的 HTTP 请求,因此在浏览器中会有一个新的页面 class 对象实例和一个全新的 HTML DOM。您为页面的先前实例所做的任何工作 class — 例如将地址列表绑定到网格 — 不再存在。
你可以通过在每次回发时重建你的网格代码来解决这个问题,但我真正要做的是跳过整个“RegisterStartupScript”混乱,而是制作网格链接直接打开 window,完全没有回发。
问题与 OnInit
事件有关。我用 OnPreLoad
替换了它,现在一切都很好。
对于搜索引擎:OnInit
事件与 RegisterStartupScript
有冲突
请考虑这种情况:
我有一个简单的页面,我想记录导致回发的所有控件。我创建了这个简单的页面。它包含一个网格来显示一些 URL,当用户点击一个图标时,一个新的标签应该打开:
<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>
和后面的代码:
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://whosebug.com" },
new Address(){ SiteAddress = "https://docs.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; }
}
到这里一切都很好。现在我为我的所有页面创建一个基础 class 并添加以下代码以查找回发控件:
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;
}
}
并更改此行:
public partial class WebForm2 : MyPageBaseClass
现在,当我单击图标时,网格视图消失了...(奇怪...)并且没有任何反应。当我评论指定行时,一切都会好起来的...(STRANGE...).
在 GetPostBackControlName
中什么都没有更改为 Request
但我不知道为什么会这样。我检查了一下,看看我是否没有在点击事件中 RegisterStartupScript
一切都很好。请帮助我们解决这个问题。
谢谢
when I click on icons grid view disappears...
ASP.Net 页面 class 对象实例的寿命仅够服务一个 HTTP 请求,默认情况下每个 HTTP 请求都会重建整个页面。
每次执行回发时,您都会有一个新的 HTTP 请求,因此在浏览器中会有一个新的页面 class 对象实例和一个全新的 HTML DOM。您为页面的先前实例所做的任何工作 class — 例如将地址列表绑定到网格 — 不再存在。
你可以通过在每次回发时重建你的网格代码来解决这个问题,但我真正要做的是跳过整个“RegisterStartupScript”混乱,而是制作网格链接直接打开 window,完全没有回发。
问题与 OnInit
事件有关。我用 OnPreLoad
替换了它,现在一切都很好。
对于搜索引擎:OnInit
事件与 RegisterStartupScript