一点背景......在工作中我从Windows XP(32位)升级到Windows 7(64位)。在升级时,我也被改为:
我正在测试我的网站,以确保没有任何损坏,而且确实存在......通过我指定的密钥在ViewState
中存储值似乎已经破坏了。
早期,我创建了一些用户控件(.ascx),让生活更轻松一些。为了保留属性,我将它们存储在ViewState
中,它在ASP.Net 2.0中运行得非常好。
属性存储示例(来自我的ValidatedTextBox
类,它是带有预定义验证程序的<asp:TextBox />
:
Private ReadOnly Property ViewStateControlPrefix() As String
Get
Return "Maggie:ValidatedTextBox:" & txt.ClientID & ":"
End Get
End Property
Public Property TextMode() As System.Web.UI.WebControls.TextBoxMode
Get
If Not ViewState(Me.ViewStateControlPrefix & "TextMode") Is Nothing Then
Return ViewState(Me.ViewStateControlPrefix & "TextMode")
Else
Return System.Web.UI.WebControls.TextBoxMode.SingleLine
End If
End Get
Set(ByVal value As System.Web.UI.WebControls.TextBoxMode)
ViewState(Me.ViewStateControlPrefix & "TextMode") = value
End Set
End Property
现在已经发生了对ASP.Net 4.5.1的更新,这不再像我想象的那样有效。
ViewStateControlPrefix
会返回我期望的内容(例如"Maggie:ValidatedTextBox:ctl00_cphMaggie_vtKeywords_txt:"
),但这不是ViewState中的密钥实际上是什么(它应该是)。
以下是调试器中发生的事情的屏幕截图:
键的差异归结为ClientID
属性。
在Get
中,它设置为ctl00_cphMaggie_vtResponse_txt
,但Set
设置为vtResponse_txt
,这使我处于亏损状态我想要检索该值。
pages
中的web.config
元素自动添加了controlRenderingCompatibilityVersion="4.0"
和clientIDMode="AutoID"
,我怀疑clientIDMode
与我的问题有关(尽管我尝试将其切换到Predictable
但没有效果。我也尝试过使用UniqueID
,但同样的问题发生了(分别为ctl00$cphMaggie$vtResponse$txt
到vtResponse$txt
)。
我假设在Set
上调用了PreInit
,因为我通过ascx中的标记设置了属性:
<Maggie:ValidatedTextBox ID="vtResponse" runat="server" CSSClass="rte" TextMode="MultiLine" Columns="60" Rows="20" IsRequiredField="false" IsValidatedField="false" ScrubberFunction="trim(normalizeWhitespace(this));" ScrubberFunctionTrigger="onchange" />
Get
明确调用PreRender
。
有人可以告诉我:
更新
将ClientIDMode
切换为Static
会使ClientID
属性非常一致(尽管当多个ValidatedTextBox
控件位于同一页面时不够独特)。
我还将此添加到控件的代码隐藏中:
Protected Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
Dim clientId As String = txt.ClientID
Dim uniqueId As String = txt.UniqueID
Dim h As Hashtable = New System.Collections.Hashtable(ViewState)
Dim i As Integer = 0 'Used for a breakpoint
End Sub
暂停Dim i As Integer
行之后,很明显,当Init
事件触发时,ClientID
属性已设置(并且以I&#的方式) 39; m曾经)。
此外,似乎没有{。1}}事件要在.ascx.vb代码隐藏中捕获(我得到PreInit
),所以现在我真的很好奇当调用属性设置器时。
更新
我已经尝试了以下所有方法:
"Event 'PreInit' cannot be found"
更改为ViewStateControlPrefix
Return "Maggie:ValidatedTextBox:" & txt.UniqueID & ":"
添加到.ascx中的clientIDMode
块。<%@ Control %>
添加到.ascx中的clientIDMode
。<asp:Textbox />
元素中循环显示AutoID
,Predictable
,Inherit
和Static
。pages
块中的AutoID
,Predictable
,Inherit
和Static
。<%@ Control %>
中的AutoID
,Predictable
,Inherit
和Static
。<asp:Textbox />
从controlRenderingCompatibilityVersion
更改为3.5
更改为4.0
。4.5
controlRenderingCompatibilityVersion
元素中删除了clientIDMode
和pages
web.config
属性(也没有成功)。我改变的事情似乎并不重要。当从getter调用时,ClientID
getter返回ViewStateControlPrefix
,并且当从getter调用时,其他内容(取决于我已经更改的内容)。
有没有人知道为什么这种行为与ASP.Net 2.0有如此根本的不同?或者如何改回来?
答案 0 :(得分:0)
我提出的解决方法是重新编写ViewStateControlPrefix
getter以返回独立于ClientIDMode
设置的唯一值:
Private ReadOnly Property ViewStateControlPrefix() As String
Get
Dim parts As String() = Me.ClientID.Split("_")
Dim id As String = Me.ClientID 'Default to ClientID
Dim prefix As String = String.Empty
If parts.Length > 0 Then
'By using Me.ClientID, the last element of the array will always be
'the ID specified in the markup, regardless of ClientIDMode settings.
id = parts(parts.GetUpperBound(0))
End If
prefix = "Maggie:ValidatedTextBox:" & id & ":"
Return prefix
End Get
End Property
这将返回一个一致的值,以用作ViewState
包中的键,无论何时调用此getter并且无论ClientIDMode
设置如何(无论何时设置它们)。
我会暂时不接受这个答案