SP2010 - httpcontext.response.write()不适用于LinkBut​​ton的onClick事件

时间:2012-08-08 13:52:12

标签: asp.net sharepoint-2010 httpcontext

可能是我错过了一个简单的疏忽(虽然我模糊地回忆起一些关于Response.Write在某些情况下没有按预期工作的内容工作的晦涩的博文,但我不记得这是否是其中之一):

情况是,我在SP2010中运行的控件上有一个链接按钮,如果我不使用HttpContext.Response.Write(),一切都按预期工作(即我可以更改标签的.Text值)。但是,如果我调用Context.Response.Write(),虽然我可以调试并逐步执行代码,但似乎没有任何事情发生(没有任何内容被写回来,并且不会出现对其他控件的更改)。它正在_layouts中的应用程序页面上运行,出现在模式对话框中。

(基本上,我正在尝试这样做 - http://acveer.wordpress.com/2011/01/25/using-the-sharepoint-2010-modal-dialog/但它不起作用。编辑:如果我将其更改为asp:Button,它仍然不起作用)

如果您有兴趣,请参阅以下代码:

的.aspx:

@ Page Language="C#" AutoEventWireup="true" ... 
<asp:LinkButton CssClass="button remove" runat="server" OnClick="remove_Click" Text="Remove" ID="remove"></asp:LinkButton>

.aspx.cs:

    public void remove_Click(object sender, EventArgs e)
    {
        ....

        //if successful
        HttpContext context = HttpContext.Current;
        if (HttpContext.Current.Request.QueryString["IsDlg"] != null)
        {
            testControl.Text = "test code";

            //doesn't work, and prevents line above from working
            Context.Response.Write("<script type='text/javascript'>alert('hi!');</script>");
            Context.Response.Flush();
            Context.Response.End();

           // context.Response.Write("<script type='text/javascript'>window.frameElement.commitPopup()</script>");
           // context.Response.Flush();
           // context.Response.End();
        }           
    }

有人遇到过类似的东西吗?

编辑:一些可能有用的有趣内容,

  • 按钮本身位于UpdatePanel
  • 我确实指定了AsyncPostbackTrigger

3 个答案:

答案 0 :(得分:3)

使用Web窗体代码中的Response.Write充其量是个问题。作为一个经验法则:永远不要使用Web窗体页面或用户控件中的Response.Write。

Response.Write存在问题的原因是因为它不是页面控件树和渲染基础结构的一部分。这意味着当在其中的事件中使用时,它将输出正常页面流之外的文本,并且通常在正确的HTML页面结构之外。

这也是当你将它们与UpdatePanels结合使用时出现问题的原因。由于UpdatePanel专门用于替换页面中的部件,因此基础架构需要知道哪些部件。 Response.Write完全在此之外发生,并且没有真正的方法知道在哪里呈现它。最好的情况是,ScriptManager将执行一个Response.Clear来清除你的Response.Writes,最坏的情况是你将破坏UpdatePanel协议体,你将得到一个JavaScript错误。

最重要的是,当您执行部分页面更新时,将忽略任何文字<script>标记,因为浏览器的innerHTML功能用于填充服务器发送的HTML片段不执行<script>标记。

现在,将所有这些理论排除在外 - 是否无法通过UpdatePanel执行一段JavaScript代码?事实证明,它比仅执行Response.Write更加清晰: ScriptManager.RegisterClientScriptBlock ScriptManager.RegisterStartupScript 。例如:

ScriptManager.RegisterClientScriptBlock(
    theButton, // control or UpdatePanel that will be rendered
    typeof(YourPage), "UniqueKey", // makes your script uniquely identifiable
    "alert('Testing!');", true);

重要的部分是第一个参数:现在ScriptManager将知道何时执行您的脚本。如果将其注册在部分页面刷新时未更新的控件上,则不会执行脚本。但是,如果包含控件的UpdatePanel已刷新,则连接到它的脚本也将执行。这通常就是你想要的。

如果您总是想要执行脚本,无论哪个面板更新,您都可以调用

ScriptManager.RegisterClientScriptBlock(Page, ... );

答案 1 :(得分:3)

@Ruben提供了一个非常好的答案,但我觉得我可以添加一些不适合评论的有用内容。

在SharePoint中,有一些情况下您使用Response.Write - 即在处理在SharePoint模式弹出窗口中显示的webpart时,您希望在使用window.frameElement.commitPopup()时使用回调做一些可爱的事情。< / p>

您在更新面板中使用Response.Write这一事实实际上是您的问题的一部分。当使用更新面板生成的回发返回时,响应的格式为UpdatePanelId|Response Content,其中UpdatePanelId是与更新面板关联的div,Response Content是div的新内部HTML 。当您使用response.write时,该格式将丢失,因此ScriptManager不知道如何处理响应,应将其忽略为错误。 @Ruben为您提供了一种在UpdatePanel中注册脚本的方法。

答案 2 :(得分:2)

Context.Response ...应该有一个小写的上下文

即:

context.Response.Flush()

还是我错过了这一点?