2012-08-08 70 views
2

可能是一個簡單的疏忽,我已經錯過了(雖然我依稀記得大概的Response.Write的內部工作按預期在某些情況下不工作一些不起眼的博文,但我不記得這是否是其中之一):SP2010 - httpcontext.response.write()不工作的LinkBut​​ton的的onClick事件

情況是,我在SP2010中運行的控件上有一個鏈接按鈕,如果我不使用HttpContext.Response.Write(),一切正常如預期的那樣(即我可以更改標籤的.Text值)。但是,如果我調用Context.Response.Write(),而我可以調試並逐步執行代碼,則似乎什麼也不會發生(沒有任何信息會被寫回來,並且不會顯示其他控件的更改)。它在_layouts中的應用程序頁面上運行,出現在模態對話框中。

(基本上,我試圖做到這一點 - http://acveer.wordpress.com/2011/01/25/using-the-sharepoint-2010-modal-dialog/但它不工作編輯:如果我將其更改爲一個ASP:按鈕,它仍然無法正常工作。)

下面是一些代碼,如果你有興趣:

的.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(); 
     }   
    } 

一nyone碰到類似的東西?

編輯:一些更有趣的作品,可以幫助,

  • 按鈕本身處於一個UpdatePanel
  • 我有一個AsyncPostbackTrigger分配

回答

3

使用來自Web Forms代碼的Response.Write存在問題。作爲一個大拇指的規則:永遠不要使用Web窗體頁面或用戶控件的Response.Write。

的回覆於原因是有問題的,是因爲它不是頁面的控制樹的一部分,和渲染架構。這意味着當在事件中使用時,它將輸出正常頁面流之外的文本,並且通常在正確的HTML頁面結構之外。

這也是爲什麼事情出差錯,當你在使用結合他們的UpdatePanel。由於UpdatePanels專門設計用於替換頁面中的部件,因此基礎結構需要知道哪些部件是。一個Response.Write完全發生在這之外,並且沒有真正的方法知道在哪裏渲染它。充其量,ScriptManager會執行一個Response.Clear來清除Response.Writes,最壞的情況是你會破壞UpdatePanel協議主體,你會得到一個JavaScript錯誤。

爲了避免在執行部分頁面更新時忽略任何文字<script>標記,因爲用於填充服務器發送的HTML片段的瀏覽器的innerHTML功能不會執行<script>標記。

現在,所有這些理論都被排除在外 - 是否沒有辦法通過UpdatePanel執行一段JavaScript代碼?事實證明,這是一個非常乾淨而不僅僅是執行一個Response.Write:ScriptManager.RegisterClientScriptBlockScriptManager.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, ...); 
+0

我希望我能給這100個upvotes - 非常感謝你!學到了堆:D – 2012-08-09 02:22:48

2

Context.Response ......應該有內小寫情況

ie:

context.Response.Flush() 

etc

還是我錯過了觀點?

+0

它編譯得很好 - 我有HttpContext上下文= HttpContext.Current;在它上面 - 我也試過了Page.Context和this.Context.Current〜 – 2012-08-08 14:24:29

+0

是的,但是你後面沒有提到'context',你指的是'Context'。您是否在單擊按鈕時嘗試使腳本顯示? – podiluska 2012-08-08 14:31:31

+1

@podiluska你是對的,它恰好是Context和HttpContext.Curret(現在是上下文)是同一個對象,所以除了未引用的變量和不必要的冗餘之外,對他的代碼沒有負面影響。 – 2012-08-08 15:18:31

3

@Ruben提供了一個很好的答案,但我覺得我可以添加不有用的內容適合評論。

在SharePoint中有幾個場合使用Response.Write - 即處理在SharePoint模式彈出窗口中顯示的Web部件,並且在使用window.frameElement.commitPopup()時想要使用回調進行可愛的操作。

事實上,您在更新面板中使用Response.Write實際上是您問題的一部分。當使用更新面板生成的回發返回時,響應格式爲UpdatePanelId|Response Content,其中UpdatePanelId是與更新面板關聯的div,Response Content是div的新內部HTML。當您使用response.write時,該格式會丟失,因此ScriptManager不知道如何處理響應,並應將其忽略爲錯誤。 @Ruben提供了一種在UpdatePanel中註冊腳本的方法。

相關問題