不能创建'System.Object'从它的字符串表示形式

本文关键字:字符串 表示 Object 创建 System 不能 | 更新日期: 2023-09-27 18:15:33

我和webforms解析器今天遇到了一些困难,关于控件属性,我希望你们中的一些人可以帮助我!

我有一个Control,其属性名为Value, object为类型。每次我在aspx中声明它都会得到错误

不能创建System类型的对象。对象'从它的字符串表示"…

什么都不是对象?:)

然后我试图在我的财产上添加一个TypeConverter,但没有运气。

我的控制
[ParseChildren(true, "Value")]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ControlBuilder(typeof(ParamControlBuilder))]
public class Param : Control
{
    public string Name { get; set; }
    [TypeConverter(typeof(StringToObjectConverter))]
    public object Value { get; set; }
    protected override void AddParsedSubObject(object obj)
    {
        base.AddParsedSubObject(obj);
    }
    public override void DataBind()
    {
        base.DataBind();
    }
    protected override void DataBindChildren()
    {
        base.DataBindChildren();
    }
}

TypeConverter

public class StringToObjectConverter : TypeConverter 
{
    public override bool IsValid(ITypeDescriptorContext context, object value)
    {
        return true;
    }
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(object))
        {
            return true;
        }
        if (destinationType == typeof(InstanceDescriptor))
        {
            return true;
        }
        return base.CanConvertTo(context, destinationType);
    }
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        return value.ToString();
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(object))
        {
            return (object)value;
        }
        if (destinationType == typeof(InstanceDescriptor))
        {
            return new InstanceDescriptor(typeof(object).GetConstructor(new Type[] { }), new object[] { });
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

我想做的是能够在我的aspx页面上写以下

<my:param name="A object" value="<# value_of_a_method()" %> runat="server" />
<my:param name="A object" value="this_is_just_a_string" runat="server" />

第一个示例工作正常,第二个示例由于上述错误而失败。不,我无法相信唯一的解决方法就是每次都进行数据绑定,即使是对于像

这样的常量字符串
<my:param name="A object" value='<%# "this_is_just_a_string" %>' runat="server" />

不能创建'System.Object'从它的字符串表示形式

添加一个实际上是序列化的ValueAsString属性并防止Value被序列化怎么样?

ValueAsString将负责适当地序列化和反序列化Value(例如XML或JSON序列化)。

事实证明,由于ASP。Net构建控件,没有办法做你想做的事情。

可以实现一种机制来获取要处理的对象类型,如字符串或内部类,但是如果你在混合中包含了基本类型,如int,框架甚至不会为你的对象值执行TypeConverter。

例如,在以下两种情况下(使用VB语法),将创建两个Params,但Param1的值将为空:
<cti:Param ID="Param1" Value="<%# CInt(1) %>" runat="server" />
<cti:Param ID="Param2" Value="test" runat="server" />

为了完整起见,下面是我是如何在没有ASP的情况下实现对象转换器的。在意识到它总是需要一个实际的类来实例化,而不仅仅是一个Object之后,Net抛出了一个fit:

首先,创建一个底层逻辑可以实例化的中间类。这个类对于每个可以实现的对象类型类都有一个构造函数:

public class MyObjectConverter
{
    public MyObjectConverter() : base()
    {
    }
    public MyObjectConverter(string oValue) : this()
    {
        this.Value = oValue;
    }
    public object Value { get; set; }
    public override string ToString()
    {
        if (this.Value == null)
        {
            return string.Empty;
        }
        else
        {
            return this.Value.ToString();
        }
    }
}

接下来,修改StringToObjectConverter的ConvertTo方法,以便它使用适当的构造函数(对象构造函数仍然会混淆这里的代码)创建新类的实例:

public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
    if (destinationType == typeof(object))
    {
        return (object)value;
    }
    if (destinationType == typeof(InstanceDescriptor))
    {
        return new InstanceDescriptor(typeof(MyObjectConverter).GetConstructor(new Type[] {value.GetType()}), new object[] {value});
    }
    return base.ConvertTo(context, culture, value, destinationType);
}

最后,在Param对象中,修改Value属性以处理新类型:

private object m_Value;
[TypeConverter(typeof(StringToObjectConverter))]
public object Value
{
    get
    {
        return m_Value;
    }
    set
    {
        if (value is MyObjectConverter)
        {
            m_Value = ((MyObjectConverter)value).Value;
        }
        else
        {
            m_Value = value;
        }
    }
}

我认为可能有可能生成动态类或构造函数或对象转换器类,但这不是我有经验的东西,所以我不能真正说出这是否是一个可行的解决方案。

所以,总的来说,这种方法有两个问题:

1)不能用于基本数据类型。但是,即使使用对象值属性而不将字符串引入到等式中,也不支持此功能。

你必须为所有你希望支持的数据类型显式定义构造函数。