如何从System.Web.UI.Control(基类)获取值?

时间:2013-02-19 15:19:32

标签: asp.net web-controls asp.net-webcontrol

有没有办法使用基类访问控件的值/文本?

查看TextBoxHiddenField,System.Web.UI.Control是他们共享的最具体的基类。看起来像个好人,但我没有看到明显的方式来访问文本/值。

我确实看到两个类定义都使用 ControlValuePropertyAttribute 来标识保存其文本/值的属性...例如HiddenField设置为“Value”,TextBox设置为“Text”。但不知道如何使用该信息来检索数据。

背景

我有一个扩展方法,它接受一些Web控件的文本(例如,TextBox)并将其转换为给定的类型:

<Extension()> _
Public Function GetTextValue(Of resultType)(ByVal textControl As ITextControl, ByVal defaultValue As resultType) As resultType
    Return ConvertValue(Of resultType)(textControl .Text, defaultValue)
End Function

现在,我需要HiddenField的值(它不实现ITextControl接口)。重载函数很容易,但是只处理基类并且不再需要处理写入重载就太棒了。

修改 - 其他信息

以下是如何使用扩展方法的示例

Dim myThing as Decimal = tbSomeWebControl.GetTextValue(Of Decimal)(0)  ' Converts the textbox data to a decimal
Dim yourThang as Date = hdnSomeSecret.GetTextValue(Of Date)(Date.MinValue)  ' Converts the hiddenfield data to a Date

目前,这需要两次重载,因为使用hiddenfields中的Value属性和文本框中的Text属性访问数据。

重载有什么问题?没什么,除了我一遍又一遍地编写几乎相同的代码(只修改定义的第一个参数和它的调用的第一个参数)。

2 个答案:

答案 0 :(得分:4)

您无法使用面向对象的方法来获取值,因为它们在继承树中没有共同的祖先,您可以从中获取数据。解决方案非常优雅,您只需传递WebControl并动态检查类型。

原谅我的C#:

(请注意,这是记事本代码,我没有运行任何代码,因此您可能需要进行一些调整)


解决方案1:直接从“请求”

获取数据

下行:不是很好的ASP.NET。但是工作呢。

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue)
{
    // If you only wish data from form, and not questy string or cookies
    // use Request.Form[control.UniqueId] instead
    string value = Request[control.UniqueId];
    return ConvertValue<ResultType>(value, defaultValue);
}

解决方案2:动态检查类型

缺点:您必须为多种控制类型提供处理

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue)
{
    if (control is ITextControl)
        return ConvertValue<ResultType>((ITextControl)control.Text, defaultValue);
    else if (control is HiddenField)
        return ConvertValue<ResultType>((HiddenField)control.Value, defaultValue);
    else if (anothertype)
        return ConvertValue<ResultType>(another_retrieval_method, defaultValue);
}

解决方案3:使用反射

下行:反射可能很棘手,看起来不优雅,并且在许多调用中可能会很慢

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue)
{
    // Get actual control type
    Type controlType = control.GetType();
    // Get the attribute which gives away value property
    Attribute attr = controlType.GetCustomAttribute<ControlValuePropertyAttribute>();
    if (attr == null)
        throw new InvalidOperationException("Control must be decorated with ControlValuePropertyAttribute");
    ControlValuePropertyAttribute valueAttr = (ControlValuePropertyAttribute)attr;
    // Get property name holding the value
    string propertyName = valueAttr.Name;
    // Get PropertyInfo describing the property
    PropertyInfo propertyInfo = controlType.GetProperty(propertyName);
    // Get actual value from the control object
    object val = propertyInfo.GetValue(control);
    if (val == null)
        val = "";

    return ConvertValue<ResultType>(val, defaultValue);
}

答案 1 :(得分:0)

我认为DataItemContainer将是您最接近的事情。