ASP.Net中的Vb6"Tag"属性等价物?

Dan*_*ola 7 asp.net controls webforms tag-property

我在这里寻找想法和意见,而不是"真正的答案",我猜......

回到旧的VB6时代,所有控件中都有一个名为"Tag"的属性,这是存储与控件相关的自定义信息的有用方法.每一个控制都拥有它,一切都很幸福......

现在,在.Net(至少对于WebForms),它不再存在了......

有人有一个很好的替代品吗?

我经常发现这个问题,我在生命周期中的不同时间运行不同的函数,并且他们使用我的控件进行操作,并且我希望将它们保持原样,但是应该将信息传递给另一个关于具体控制.

我可以想到一百万个替代品(显然是从模块级字典开始),但没有一个像好的标签一样干净.

(注意:我知道我可以将所有控件子类化并使用我的版本.我宁愿不这样做)

有什么建议?你是如何解决这个问题的?关于他们为什么首先删除这个的任何想法?

编辑:我正在寻找内部请求,而非内部请求.我不需要这些信息仍然在PostBack上.例如,这是在_Load和_PreRender方法之间.

编辑2:我知道我的ASp.Net,我确实知道桌面和网络之间的区别,伙计们!我只是想尝试使用.Net给我的最大化的抽象.我理解这些权衡,相信我,请假设我这样做.

mdb*_*mdb 5

不,没有直接的等效项,但是如果您使用的是框架的 v3.5,则可以使用扩展方法轻松添加此功能。例如:

Imports System.Runtime.CompilerServices

Public Module Extensions
  <Extension()> _
  Public Sub SetTag(ByVal ctl As Control, ByVal tagValue As String)
    If SessionTagDictionary.ContainsKey(TagName(ctl)) Then
        SessionTagDictionary(TagName(ctl)) = tagValue
    Else
        SessionTagDictionary.Add(TagName(ctl), tagValue)
    End If
  End Sub

  <Extension()> _
  Public Function GetTag(ByVal ctl As Control) As String
    If SessionTagDictionary.ContainsKey(TagName(ctl)) Then
        Return SessionTagDictionary(TagName(ctl))
    Else
        Return String.Empty
    End If
  End Function

  Private Function TagName(ByVal ctl As Control) As String
    Return ctl.Page.ClientID & "." & ctl.ClientID
  End Function

  Private Function SessionTagDictionary() As Dictionary(Of String, String)
    If HttpContext.Current.Session("TagDictionary") Is Nothing Then
        SessionTagDictionary = New Dictionary(Of String, String)
        HttpContext.Current.Session("TagDictionary") = SessionTagDictionary
    Else
        SessionTagDictionary = DirectCast(HttpContext.Current.Session("TagDictionary"), _ 
          Dictionary(Of String, String))
    End If
  End Function
End Module
Run Code Online (Sandbox Code Playgroud)

然后,在您的 ASP.NET 页面中,首先将您的扩展引入范围,例如:

Imports WebApplication1.Extensions
Run Code Online (Sandbox Code Playgroud)

...然后根据需要使用它您的控件:

TextBox1.SetTag("Test")

Label1.Text = TextBox1.GetTag
Run Code Online (Sandbox Code Playgroud)

后期编辑:如果您真的,真的不想将您的标签存储在 Session 对象中,则可以将它们填充到您的 Viewstate 中。这当然意味着您的标签在发送给用户的页面标记中公开(尽管以混淆形式),不幸的是,需要一些反射功能,因为页面的 ViewState 属性被标记为“受保护的” ' 因为某些原因。

所以,这段代码应该只考虑用于娱乐目的,除非你真的喜欢在代码审查期间引起注意:

<Extension()> _
  Public Sub SetTag(ByVal ctl As Control, ByVal tagValue As String)
    ViewState.Add(ctl.ID & "_Tag", tagValue)
  End Sub

<Extension()> _
  Public Function GetTag(ByVal ctl As Control) As String
    Return ViewState(ctl.ID & "_Tag")
  End Function

Private Function ViewState() As Web.UI.StateBag
    Return HttpContext.Current.Handler.GetType.InvokeMember("ViewState", _
                Reflection.BindingFlags.GetProperty + _
                Reflection.BindingFlags.Instance + _
                Reflection.BindingFlags.NonPublic, _
                Nothing, HttpContext.Current.CurrentHandler, Nothing)
End Function
Run Code Online (Sandbox Code Playgroud)

最终编辑(我保证......)。这是一种摆脱反射的方法:首先,创建一个新类来公开具有可用保护级别的 ViewState 属性,然后更改您的代码隐藏 (.aspx.vb) 类以继承它而不是 Web.UI。页面,例如:

Public Class PageEx
  Inherits System.Web.UI.Page

  Friend ReadOnly Property ViewStateEx() As Web.UI.StateBag
    Get
        Return MyBase.ViewState
    End Get
  End Property
End Class
Run Code Online (Sandbox Code Playgroud)

现在,在您的扩展模块中,您可以访问这个新定义的属性:

Private Function ViewState() As Web.UI.StateBag
  Return DirectCast(HttpContext.Current.Handler, PageEx).ViewStateEx
End Function
Run Code Online (Sandbox Code Playgroud)

仍然有点黑客,但比使用反射更容易接受......