Почему мой ретранслятор продолжает давать сбой при значениях Eval (NULL)?

<asp:Repeater ID="rptLessons" runat="server">
    <ItemTemplate>
        <tr>

            <td><%#Eval("fullname")%></td>
            <td><%#isCompleted(Eval("totallessons"), Eval("completedlessons"), Eval("totalNumAvail"), Eval("totalNumCorrect"))%></td>
            <td><%#FormatPercent(Eval("totalnumcorrect") / Eval("totalNumAvail"))%> <%-- (<%#Eval("totalnumcorrect")%> / <%#Eval("totalNumAvail")%>) --%></td>
            <td><%#FormatPercent(Eval("completedlessons") / Eval("totallessons"))%> <%-- (<%#Eval("completedlessons")%> / <%#Eval("totallessons")%>) --%></td>
            <td><%#Eval("lastaccessed")%></td>
        </tr>
    </ItemTemplate>
   </asp:Repeater>

Я не могу понять этого, но как только он попадает в какие-то данные NULL, он отказывается переходить к рисованию следующих элементов.

Ответов (4)

Решение

Чтобы быть уверенным, вам нужно указать трассировку стека.

Но я вижу несколько проблем:

  1. DIV # 0 ошибки внутри FormatPercent
  2. NULL ошибки.

Пример решения

(System.Convert.ToInt32 должен преобразовать DBNull / NULL в 0)

Или измените isCompleted, чтобы принять параметры объекта и выполнить проверку NULL / DBNull внутри функции.

Если бы мне пришлось угадывать, я бы сказал, что ваша функция isCompleted не обрабатывает значения Nothing . Это предположение, потому что функция не указана в вашем примере.

При немного другом подходе, который может быть полезным, будет выполнение ваших вычислений в коде, а не в разметке. Просто проще проверить наличие нулей и т. Д. Я почти всегда иду по этому пути с чем-либо, кроме простого Eval () в моей разметке.

<td>
    <%#GetCorrectPercent()%>
</td> 

protected string GetCorrectPercent()
{
    if(Eval("totalnumcorrect") == null || Eval("totalNumAvail") == null)
        return "n/a";

    return ((int)Eval("totalnumcorrect") / (int)Eval("totalNumAvail")).ToString();
}

Не уверен, что все форматирование здесь правильное, но это должно заставить вас двигаться в другом направлении. Eval () будет работать в вызываемых методах, пока вызывающий объект выполняет DataBind ().

Я больше склоняюсь к явному. Простите за мелкие ошибки в коде, я не могу это проверить.

Если в вашей разметке вы замените эти числа на литералы, то в коде позади:

Если у вас есть коллекция MyClass.

В событии инициализации вашей страницы

this.rptLessons.OnItemDataBound += rptLessons_DataBound...

В нагрузке или где бы вы ни выбрали

this.rptLessons.DataSource = CollectionOfMyClass;
this.rptLessons.DataBind();

Затем в этом itemDataBoundEvent

MyClass myClass = (MyClass)ri.DataItem;
Literal litFullname = FindControl(ri, "litFullName");
litFullName.Text = myClass.Fullname;

Таким образом, вы можете обрабатывать нули и т. Д. Более контролируемым способом, чем использование eval.