仅当item中存在属性时才在aspx中使用Eval - 抛出DataBinding异常

时间:2015-02-08 10:03:25

标签: c# asp.net .net

我有一个aspx页面,其中包含一个包含5个字段的转发器。 这些字段填充了两种不同的项目类型。 一个项目有3个属性:" A" " B" " C"而另一个有" A" " B" " C" " d" " E"

我想为两者使用相同的转发器,但只显示每个转发器的相关属性。 当试图在一个有利的时候使用Eval" D"与项目1我得到错误: DataBinding:' Item1'不包含名称为' D'。

的媒体资源

我尝试使用if语句,但它没有帮助,当尝试使用" ItemDataBound"在尝试加载Item1时它也会引发异常(在尝试加载具有所有属性的Item2时不抛出。

如果属性存在,我怎么才能评估?

1 个答案:

答案 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行为的解决方法。