加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 动态UpdatePanels和UserControls问题

发布时间:2020-12-16 03:16:08 所属栏目:asp.Net 来源:网络整理
导读:在将项目从3.5迁移到4.5时,在ASP.Net WebForms中遇到了一个有趣的问题. 有问题的网站非常动态 – 该网页是基于CMS方式的配置构建的. 但是在4.5中我们遇到了一个问题 – 当通过按钮点击将更多内容添加到页面中时,并不会显示内容的所有标记. (测试时问题也在.n
在将项目从3.5迁移到4.5时,在ASP.Net WebForms中遇到了一个有趣的问题.

有问题的网站非常动态 – 该网页是基于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机器:重新创建了问题.
>接下来,我的旧开机,运行VS2012 Express For Web:没有重现问题

所以它看起来像这个问题仅限于VS2013.接下来在VS2013中尝试一些不同的设置.

现已发布到Microsoft Connect here.

解决方法

解决方法

我现在有一个解决这个问题的方法.我正在使用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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读