我和webforms解析器今天有一些困难,关于控制属性我希望你们中的一些人可以帮助我!
我有一个名为Value且Control
属性的object
作为类型。每当我在我的aspx中声明它时,我都会收到错误
无法从其字符串创建“System.Object”类型的对象 代表'...'代表'价值'属性。
Wtf,不是所有对象? :)
然后我尝试在我的财产上添加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" />
答案 0 :(得分:2)
如果添加ValueAsString
属性实际上是序列化的属性并阻止Value
被序列化呢?
ValueAsString
将负责适当地序列化和反序列化Value
(例如XML或JSON序列化)。
<强>更新强> 事实证明,由于ASP.Net构建控件的方式,没有办法做你想做的事情。
可以实现一种机制来获取要处理的对象类型(如字符串或内部类),但如果在混合中包含基本类型(如Int),框架甚至不会为您执行TypeConverter对象值。
例如,在以下两种情况下(使用VB语法),将创建两个参数,但Param1的值将不存在:
<cti:Param ID="Param1" Value="<%# CInt(1) %>" runat="server" />
<cti:Param ID="Param2" Value="test" runat="server" />
为了完整性,这里是我能够实现一个对象转换器而不让ASP.Net在意识到它总是需要一个实际的类来实例化而不仅仅是一个Object之后抛出一个拟合的方式:
首先,创建一个底层逻辑可以实例化的中间类。这个类将为每个可以实现的对象类型类都有一个构造函数:
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;
}
}
}
我想可能有可能生成动态类或构造函数或对象转换器类,但这不是我所经历过的,所以我无法真正谈论这是否是一个可行的解决方案。< / p>
总而言之,这种方法存在两个问题:
1)您不能将它用于原始数据类型。但是,即使使用Object Value属性而不将字符串放入等式中也不支持此功能。
2)您必须为您希望支持的所有数据类型明确定义构造函数。