不能创建'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" />
添加一个实际上是序列化的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)不能用于基本数据类型。但是,即使使用对象值属性而不将字符串引入到等式中,也不支持此功能。