views:

1427

answers:

4
<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>

I can't figure it out but as soon as it hits some NULL data it refuses to move on to drawing the next elements.

A: 

If I had to guess, I would say that your isCompleted function doesn't handle values of Nothing. This is a guess because the function hasn't been listed in your example.

Andrew Shepherd
<%@ Page Language="VB" ...
shogun
I commented out that line and it still crashes...
shogun
Using HTML comments around ASP.NET data binding does not prevent the databinding from occurring. it just puts the result inside HTML comments in the rendered page. You need to remove it.
Roger Willcocks
A: 

You need to give a stack trace to be sure.

But I can see several issues:

  1. DIV#0 errors inside FormatPercent
  2. NULL errors.

Example Solution

<%#isCompleted(System.Convert.ToInt32(Eval("totallessons")), System.Convert.ToInt32(Eval("completedlessons")), System.Convert.ToInt32(Eval("totalNumAvail")), System.Convert.ToInt32(Eval("totalNumCorrect")))%>

(System.Convert.ToInt32 should convert DBNull/NULL to 0)

Or alter isCompleted to accept Object paramters and do your NULL / DBNull checking inside the function.

Roger Willcocks
man I had so much hope on this one but it's still not drawing it draws the firstname of the row of data that contains the NULL value but none of the other ones get drawn and it doesn't draw any more repeaters after that one...
shogun
Turn tracing on and see what the reported exception is. zyou might be failing inside isCompleted (for example on a DIV#0) rather than a NULL reference issue now.
Roger Willcocks
+1  A: 

On slightly different approach that might be helpful would be to do your computations in your code behind rather than inline in the markup. Just easier to check for nulls etc. I almost always go down this path with anything other than a simple Eval() in my markup.

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

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

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

Not sure all the formatting is correct here but this should get you going in a different direction. Eval() will work within the called methods so long as the caller is current performing a DataBind().

Andrew Robinson
will the code behind be able to see the Eval("totalnumcorrect") or do I have to pass it over, I don't understand how it would see that...
shogun
Will work but only when the GetCorrectPercent() method is called during a DataBind() operation. Calling it outside of DataBind() will result in an exception.
Andrew Robinson
Ryan, please note that this approach won't directly solve your issue, but it is much easier to check for nulls and user more complex logic that approach you are using (with all formatting in the markup.)
Andrew Robinson
A: 

I tend more towards the explicit. Forgive any minor mistakes in the code, I'm not able to test this.

If in your markup you swap out those evals for literals then in the code behind:

If you have a collection of MyClass.

In your page's init event

this.rptLessons.OnItemDataBound += rptLessons_DataBound...

In the load or where ever you choose

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

Then in that itemDataBoundEvent

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

This way you can cater for nulls etc in a more controlled way than using eval.

TreeUK