2013-12-09 29 views
5

Đã gặp phải một vấn đề thú vị trong ASP.Net WebForms khi di chuyển dự án từ 3,5 đến 4,5.Sự cố Cập nhật Động và sự cố UserControls

Trang web được đề cập vô cùng năng động - trang được xây dựng dựa trên cấu hình theo kiểu CMS.

Tuy nhiên trong 4.5 chúng tôi gặp sự cố - khi có thêm nội dung được thêm vào trang thông qua nhấp chuột vào nút, không phải tất cả đánh dấu cho nội dung đều xuất hiện. (Trên thử nghiệm vấn đề được sao chép trong. Net 4.0 là tốt).

Để minh họa ở đây là một ví dụ bị loại bỏ nhiều chỉ sử dụng mẫu dự án WebForms mặc định (trong VB trong trường hợp này).

Trong Default.aspx thêm đánh dấu sau:

<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> 

Trong Default.aspx.vb thêm đoạn mã sau:

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 

Lưu ý: Có một bảng điều khiển gói ở đây giữa điều khiển người dùng và bảng điều khiển cập nhật. Điều này phục vụ để chứng minh đánh dấu nào bị thiếu trên đầu ra.

Tạo một Control.ascx và thêm dòng sau:

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

Một khi chúng ta nhấp vào btnGo điều khiển, bảng điều khiển wrapper và control.ascx nên được thêm vào trang.

Trong Net 3.5 đó là chính xác những gì sẽ xảy ra:

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

Trong Net 4.5, các gói bảng điều khiển không xuất hiện - chỉ là điều khiển người dùng:

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

Vấn đề doesn' t xảy ra nếu bảng cập nhật nằm trong đánh dấu trang web, tuy nhiên điều đó là không thể trong trường hợp này.

Chuyển tải quá tải LoadControl được sử dụng (sang LoadControl(type,params) tạo bảng điều khiển bao bọc, nhưng không đánh dấu - dường như có vấn đề riêng với điều này).

Kiểm tra cơ thể phản ứng trong Fiddler2 cho thấy bảng điều khiển wrapper được bỏ qua ở phía máy chủ (tức là chúng ta không mất nó trong việc xử lý phía khách hàng ajax)

Vậy là có bất kỳ cách giải quyết, hoặc thậm chí một số loại sửa chữa bản vá cho hành vi này - nó dường như là một vỡ trong .Net 4 cho rằng nó đã được tốt trong 3,5.

Hiện cũng đã đăng nội dung này trên blog here để thu thập mọi nỗ lực tôi thực hiện để khắc phục hoặc giải quyết sự cố.

Cập nhật

Tiếp theo một con trỏ từ @ jadarnel27 rằng các bước dưới đây không tạo lại vấn đề trên VS2010, tôi đã thử các bước trên một vài máy ra khỏi công việc.

  • Trước một máy VS2013 khác: Đã tạo lại sự cố.
  • Tiếp theo, máy dev cũ của tôi, chạy VS2012 Express cho Web: Không tạo lại vấn đề

Vì vậy, nó trông giống ở giai đoạn này như vấn đề được giới hạn VS2013. Tiếp theo để thử một vài cài đặt khác nhau trong VS2013.

Hiện đã đăng bài đăng này lên Microsoft Connect here.

+0

Nếu bạn kiểm tra cây điều khiển (nhìn từ trang xuống đến điều khiển, sử dụng thuộc tính Điều khiển) là bảng điều khiển trong cây hay không phải là nó? Điều này là để phân biệt nếu vấn đề là ở phía máy chủ hoặc trong các kịch bản ajax. Bạn nên kiểm tra điều này trong sự kiện kết xuất trước. – JotaBe

+0

@JotaBe: Đánh dấu được gửi trở lại không chứa trình bao bọc - được kiểm tra ở chế độ khó hiểu, xem nội dung phản hồi. –

+0

@ jadarnel27. Nó thật thú vị. Chúng tôi đã có nó trên tất cả các máy ở đây. Sẽ kiểm tra thiết lập nhà của tôi. –

Trả lời

1

Cách giải quyết

Tôi hiện đang có công việc. Tôi đang sử dụng một điều khiển UserControlLoader máy chủ để bọc điều khiển người dùng, và làm cho nó riêng rẽ bằng cách ghi đè RenderContents

Mã này cho UserControlLoader là:

''' <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 

Cách sử dụng:

Để thực hiện điều này vào vui chơi giải trí các bước được liệt kê, trình xử lý sự kiện btnGo trở thành:

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

Trong trường hợp của tôi, tôi đã có cùng một vấn đề khi sử dụng VS2013 Professional mà không cần cập nhật. Tôi cho rằng đó là một lỗi liên quan đến máy chủ ứng dụng nhúng được bao gồm trong bản instalation (IIS Express). Cập nhật IDE với gói cập nhật cuối cùng (Bản cập nhật VS2013 5), sự cố đã biến mất!

Các vấn đề liên quan