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

Fel*_*Net 4 .net c# asp.net

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

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

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

如果财产存在,我怎能估算?

Ale*_*kiy 6

要解决您的问题,了解如何Eval在幕后工作是很重要的.

Eval语句转换为DataBinder.Eval在aspx编译阶段调用方法.这意味着表达式<%# 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));
}
Run Code Online (Sandbox Code Playgroud)

要抑制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";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在转发器内使用它:

<asp:Label runat="server" Text='<%# SafeEval(Container.DataItem, "A")  %>'></asp:Label>
Run Code Online (Sandbox Code Playgroud)

虽然这将解决您的问题,但这将暴露另一个问题,例如在绑定表达式确实错误/错误输入时没有错误通知.所以我建议为每个项目类型使用两个不同的中继器,而不是试图找到标准ASP.NET Eval行为的变通方法.