2013-12-09 28 views
5

將項目從3.5遷移到4.5時,在ASP.Net WebForms中遇到了一個有趣的問題。Dynamic UpdatePanels和UserControls問題

該網站非常具有動態性 - 該網頁是基於CMS時尚配置構建的。

但是,在4.5版中,我們遇到了一個問題 - 當通過點擊按鈕將更多內容添加到頁面中時,並不是所有內容的標記都會出現。 (在測試時,問題也在.net 4.0中重現)。

這裏演示的是一個很簡單的例子,它只是使用默認的WebForms項目模板(在本例中是VB)。

Default.aspx中添加以下標記:

<asp:UpdatePanel ID="udpTrigger" runat="server" UpdateMode="Always"> 
    <ContentTemplate> 
     <asp:button id="btnGo" runat="server" Text ="Go" /> 
    </ContentTemplate> 
</asp:UpdatePanel> 
<asp:Panel ID="pnlContainer" runat="server"> 
</asp:Panel> 

在Default.aspx.vb添加以下代碼:

Dim _udp As UpdatePanel 

Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init  
    _udp = New UpdatePanel() 
    _udp.ID = "udpTarget" 
    _udp.UpdateMode = UpdatePanelUpdateMode.Conditional 

    pnlContainer.Controls.Add(_udp)   
End Sub 

Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click  
    Dim ctrl = LoadControl("Control.ascx")   

    Dim pnlWrapper = New Panel With {.ID = "pnlWrapper"} 
    pnlWrapper.Controls.Add(ctrl) 

    _udp.ContentTemplateContainer.Controls.Add(pnlWrapper)   
    _udp.Update()    
End Sub 

注:有一個包裹面板這裏在用戶控件和更新面板之間。這用來演示輸出中缺少哪些標記。

創建Control.ascx並添加以下內容:

<asp:Panel ID="pnlControl" runat="server"></asp:Panel> 

一旦我們點擊btnGo控制,包裝板和control.ascx應添加到頁面。

在.net 3.5,這正是發生了什麼:

<div id="pnlContainer">      
    <div id="udpTarget"> 
     <div id="pnlWrapper"> 
      <div id="ctl05_pnlControl"> 
      </div> 
     </div> 
    </div> 
</div> 

在.NET 4.5中,包裝盤不出現 - 只要用戶控制:

<div id="MainContent_pnlContainer">   
    <div id="MainContent_udpTarget"> 
     <div id="MainContent_ctl02_pnlControl"> 
     </div> 
    </div> 
</div> 

問題沒有按」如果更新面板處於網頁的標記中,則會發生,但在這種情況下這是不可能的。

切換使用LoadControl超載(到LoadControl(type,params)產生包裝面板,但沒有標記 - 這似乎是一個單獨的問題)。

檢查中fiddler2響應正文顯示,包裝紙板是在服務器端省去(即我們不是在客戶端AJAX處理失去它)

那麼,有沒有解決辦法,甚至某種修復此行爲的修補程序 - 它確實在.Net 4中發生了斷裂,因爲它在3.5中正常。

現在,我現在也在我的blog here上發佈了此信息,以收集我爲獲得修復或解決方法所做的任何嘗試。

更新

在從@ jadarnel27了下面的步驟並未照VS2010問題的一個指針,我已經試過一對夫婦的機器遠離工作的步驟。

  • 首先關閉另一臺VS2013機器:重新創建問題。
  • 接下來,我的老dev的機器,運行VS2012 Express的網頁:沒有重現該問題

所以看起來在這個階段喜歡的問題僅限於VS2013。接下來在VS2013中嘗試一些不同的設置。

已發佈此信息至Microsoft Connect here

+0

如果檢查控制樹(從頁面向下看控件,使用控件屬性)是樹中的面板還是不在那裏?這是爲了分辨問題出在服務器端還是在ajax腳本中。你應該在預渲染事件中檢查它。 – JotaBe

+0

@JotaBe:發回的標記不包含包裝 - 在fiddler中檢查,查看響應內容。 –

+0

@ jadarnel27。那很有意思。我們已經在這裏的所有機器上使用它。將測試我的家庭設置。 –

回答

1

解決方法

我現在有一個解決方法。我使用的是UserControlLoader服務器控件包用戶控制,並通過覆蓋RenderContents

代碼爲UserControlLoader單獨渲染,它是:

''' <summary> 
''' UserControl Loader - loads a user control 
''' Works around a problem with ASP.Net Webforms in 4.0/4.5 
''' </summary> 
<ToolboxData("<{0}:UserControlLoader runat=server></{0}:UserControlLoader>")> _ 
Public Class UserControlLoader 
    Inherits WebControl 

    Public ReadOnly Property Control As Control 
     Get 
      Return _control 
     End Get 
    End Property 
    Private _control As Control 

    Public Sub LoadControl(page As Page, virtualPath As String) 
     _control = page.LoadControl(virtualPath) 
     Me.Controls.Add(_control) 
    End Sub 

    Public Overrides Sub RenderBeginTag(writer As HtmlTextWriter) 
     'Don't render anything 
    End Sub 

    Public Overrides Sub RenderEndTag(writer As HtmlTextWriter) 
     'Don't render anything 
    End Sub 

    ''' <summary> 
    ''' Overrides RenderContent to write the content to a separate writer, 
    ''' then adds the rendered markup into the main HtmlTextWriter instance. 
    ''' </summary> 
    Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter) 

     If _control Is Nothing Then Return 

     Using sw = New StringWriter() 
      Using hw = New HtmlTextWriter(sw) 

       MyBase.RenderContents(hw) 

       writer.Write(sw.ToString) 

      End Using 
     End Using 

    End Sub 

End Class 

用法:

落實到娛樂本列出的步驟,將btnGo事件處理程序變爲:

Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click 

    Dim loader = new UserControlLoader() 
    loader.LoadControl(Page,"Control.ascx")  

    Dim pnlWrapper = New Panel With {.ID = "pnlWrapper"} 
    pnlWrapper.Controls.Add(loader) 

    _udp.ContentTemplateContainer.Controls.Add(pnlWrapper)   
    _udp.Update() 

End Sub 
0

在我的情況,我使用VS2013 Professional時沒有應用更新也有同樣的問題。我認爲這是與安裝(IIS Express)一起提供的嵌入式應用程序服務器的相關錯誤。使用最新的更新包(VS2013 Update 5)更新IDE,問題消失了!