我有一个aspx页面,其中包含一个包含5个字段的转发器。 这些字段填充了两种不同的项目类型。 一个项目有3个属性:" A" " B" " C"而另一个有" A" " B" " C" " d" " E"
我想为两者使用相同的转发器,但只显示每个转发器的相关属性。 当试图在一个有利的时候使用Eval" D"与项目1我得到错误: DataBinding:' Item1'不包含名称为' D'。
的媒体资源我尝试使用if语句,但它没有帮助,当尝试使用" ItemDataBound"在尝试加载Item1时它也会引发异常(在尝试加载具有所有属性的Item2时不抛出。
如果属性存在,我怎么才能评估?
答案 0 :(得分:6)
要解决您的问题,了解Eval
如何在幕后工作非常重要。
Eval
语句转换为在aspx编译阶段调用DataBinder.Eval
方法。这意味着表达式<%# Eval("A") %>
是<%# DataBinder.Eval(Container.DataItem, "A") #>
的缩短版本。如果您将遵循Eval
方法的执行路径,如果容器对象不包含属性,您将看到GetPropertyValue
中抛出异常:
// get a PropertyDescriptor using case-insensitive lookup
PropertyDescriptor pd = GetPropertiesFromCache(container).Find(propName, true);
if (pd != null) {
prop = pd.GetValue(container);
}
else {
throw new HttpException(SR.GetString(SR.DataBinder_Prop_Not_Found, container.GetType().FullName, propName));
}
要取消Eval
引发的异常,您可以编写自己的SafeEval
方法并将其放在基页类中:
public abstract class BasePage: Page
{
public object SafeEval(object container, string expression)
{
try
{
return DataBinder.Eval(container, expression);
}
catch (HttpException e)
{
// Write error details to minimize the harm caused by suppressed exception
Trace.Write("DataBinding", "Failed to process the Eval expression", e);
}
return "Put here whatever default value you want";
}
}
然后在转发器中使用它:
<asp:Label runat="server" Text='<%# SafeEval(Container.DataItem, "A") %>'></asp:Label>
虽然这将解决您的问题,但这会暴露另一个问题,例如在绑定表达式确实错误/错误输入时没有错误通知。所以我建议为每个项目类型设置两个不同的中继器,而不是试图找到标准ASP.NET Eval
行为的解决方法。