如何在gridview的rowcommand事件中的新选项卡中打开页面?

我有以下代码:

protected void gv_inbox_RowCommand(object sender, GridViewCommandEventArgs e) { int index = Convert.ToInt32(e.CommandArgument); if (e.CommandName == "sign") { Session["TransYear"] = int.Parse(((HiddenField)gv_inbox.Rows[index].Cells[1].FindControl("HDN_TransYear")).Value); Session["MailNumber"] = int.Parse(((HiddenField)gv_inbox.Rows[index].Cells[1].FindControl("HDN_MailNumber")).Value); Response.Redirect("Signature.aspx", false); //Response.Write(""); //Response.Write("window.open('Signature.aspx','_blank')"); //Response.Write(""); } } 

我想在新的标签页或窗口中打开页面。 注释代码执行此操作但refresh原始页面时会导致错误。如何在我的gridview的行命令事件中以正确的方式在新窗口或选项卡中打开Signature.aspx

您要做的是使用ScriptManager进行JavaScript调用。

您定义的JavaScript代码段有效,但是,您需要ScriptManager来为您执行它。

 String js = "window.open('Signature.aspx', '_blank');"; ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Open Signature.aspx", js, true); 

使用Response.Write的问题是在PostBack期间,浏览器不会执行脚本标记。 另一方面,当使用ScriptManager.RegisterClientScriptBlock ,ASP.NET ScriptManager将自动执行代码。

更新 – 2013/02/14

正如Vladislav的回答所建议的那样,使用ClientScriptScriptManager ; 不同之处在于ClientScript仅用于同步回发(没有asp:UpdatePanel ),而ScriptManager用于异步回发(使用asp:UpdatePanel )。

另外,根据下面作者的评论 – 在asp:UpdatePanel包含asp:GridView将消除确认刷新的浏览器消息。 在同步回发(无asp:UpdatePanel )之后刷新页面时,浏览器将重新发送最后一个命令,导致服务器再次执行相同的过程。

最后,当将asp:UpdatePanelScriptManager.RegisterClientScriptBlock结合使用时,请确保将第一个和第二个参数更新为asp:UpdatePanel对象。

 ScriptManager.RegisterClientScriptBlock(updatePanel1, updatePanel1.GetType(), "Open Signature.aspx", js, true); 

首先,这里的练习是如何将简单值从一个页面传递到另一个页面。

在你的情况下,这些只是键/值,所以你可以通过GET传递它们。

您需要每行渲染一次,而不是命令按钮。

  Sign  

在此示例中,value1和value2分别是您写入HDN_TransYear和HDN_MailNumber的值。

在Signature.aspx中,如果要使用会话变量,则必须执行以下操作:

 Session["TransYear"] Session["MailNumber"] 

现在应该改为:

 Request.QueryString["TransYear"] Request.QueryString["MailNumber"] 

这通常可以满足您的要求。 但…

如果你说这个方法不安全,那么任何人都可以通过更改参数值来使用查询字符串变量,然后……

计算每一行的签名,将此签名作为第三个参数放在您的查询字符串中,并validation另一方的值和签名。

如何计算签名,嗯,这取决于你。 那是你的秘诀 。 有许多散列函数和salting算法。

作为一个非常简单的例子:

 string signature = CRC32(HDN_TransYear + "stuff that you only know" + HDN_MailNumber) 

那你的链接应该是这样的:

  Sign  

在Signature.aspx中,您使用查询字符串中的值和“您只知道的东西”来再次计算CRC32签名,并根据在查询字符串中作为参数传递的签名进行validation。

没有戏剧。

我宁愿使用ClientScript.RegisterStartupScript(this.GetType(), "Open Signature.aspx", js, true); 而且您不需要刷新页面。 页面从回发中恢复后将触发脚本块。

并且只是一个建议: – 在您的情况下是否可以使用DataKeys来检索TransYear和MailNumber的值而不是使用HiddenFields

我们已成功使用以下代码多年。 这几种方法是从一个更大的通用模块中提取出来的,但我想我已经包含了所有内容……

 public class Utilities { ///  /// This will return the first parent of the control that is an update panel ///  /// The source control /// The first parent found for the control. Null otherwise public static UpdatePanel GetFirstParentUpdatePanel(Control source) { Page currentPage = source.Page; UpdatePanel updatePanel = null; Type updatePanelType = typeof(UpdatePanel); object test = source.Parent; while (test != null && test != currentPage) { // is this an update panel if (test.GetType().FullName == updatePanelType.FullName) { // we've found the containing UpdatePanel updatePanel = (UpdatePanel)test; } // check the next parent test = ((Control)test).Parent; } // next test return updatePanel; } ///  /// This will open the specified url in a new window by injecting a small script in /// the current page that is run when the page is sent to the client's browser. /// This method accounts for the presence of update panels and script managers on the /// page that the control resides in. ///  /// The control that the call is being made from /// The URL to bring up in a new window public static void RedirectToNewWindow(Control source, string url) { // create the script to register string scriptKey = "_NewWindow"; string script = "window.open('" + url + "');"; RegisterControlScript(source, scriptKey, script); } ///  /// This will register a script for a specific control accounting for the control's UpdatePanel /// and whether or not there is a script manager on the page ///  /// The control that will be affected by the script /// A unique key for the script /// The script that will affect the control public static void RegisterControlScript(Control source, string scriptKey, string script) { // get the control's page Page currentPage = source.Page; // does the control reside in an UpdatePanel UpdatePanel updatePanel = GetFirstParentUpdatePanel(source); // did we find the UpdatePanel if (updatePanel == null) { // register the script on the page (works outside the control being in an update panel) currentPage.ClientScript.RegisterStartupScript(currentPage.GetType(), scriptKey, script, true /*addScriptTags*/); } else { // register the script with the UpdatePanel and ScriptManger ScriptManager.RegisterClientScriptBlock(source, source.GetType(), scriptKey, script, true /*addScriptTags*/); } // did we find the UpdatePanel } } 

然后,为了你的使用,你打电话

 protected void gv_inbox_RowCommand(object sender, GridViewCommandEventArgs e) { int index = Convert.ToInt32(e.CommandArgument); if (e.CommandName == "sign") { Session["TransYear"] = int.Parse(((HiddenField)gv_inbox.Rows[index].Cells[1].FindControl("HDN_TransYear")).Value); Session["MailNumber"] = int.Parse(((HiddenField)gv_inbox.Rows[index].Cells[1].FindControl("HDN_MailNumber")).Value); Utilities.RedirectToNewWindow(gv_inbox, "Signature.aspx"); } } 

不是最简洁的代码,因为我已经提取了这些帮助方法,但你明白了。 上面的代码将在c#2.0及更高版本上运行,无论UpdatePanel嵌套如何,或者即使根本没有使用UpdatePanel也可以使用

为什么要在打开新窗口之前设置会话?

如果打开新窗口设置会话是可以的,我认为您可以在Signature.aspx后面的代码中执行此操作,考虑到您已将所需参数作为查询字符串传递为@David指出。

为什么我们使用回帖在URL的不同窗口中打开链接。

在创建控制链接时,我们可以将links.aspx所需的值作为Querystring嵌入到链接控件上,它只是一个简单的浏览器点击。

我希望这很简单干净。