locked
ternary operator to deal with NULL columns - not working RRS feed

  • Question

  • User379720387 posted

    Suppose I have a query result:

    id, isCompleted, MinutesFraction

    1, true, 12

    2, false, NULL

    MinutesFraction comes from: CAST(ROUND(((DATEDIFF(second, ttInStamp, ttOutStamp)/60.0/60.0) - (FLOOR(DATEDIFF(second, ttInStamp, ttOutStamp)/60.0/60.0)))*60, 0) AS INT) as MinutesFraction

    In the webGrid I have:

    grid.Column("MinutesFraction", "Minutes", format: @<text>@item.isCompleted ? @item.MinutesFraction.ToString("00") : ""</text>)

    Compiler stumbles on "Cannot perform runtime binding on a null reference"

    I am thinking that the compiler does not like NULL, but the binding should not happen because isCompleted = false, right?

    Tuesday, July 15, 2014 5:07 PM

Answers

  • User938738290 posted

    I think the original issue is that the left side of the unary ? consists of:

    @item.isCompleted

    Which, because of the @, is going to return a HelperResult, not a bool.  It may evaluate to true when the compiler forces it to bool, which means that this the ToString( ) call may be getting executed regardless of the actual value of item.isComplete.

    Try this:

    grid.Column("MinutesFraction", "Minutes", format: @<text>@(item.isCompleted ? item.MinutesFraction.ToString("00") : "")</text>)

    The @<text> forces everything between it and the </text> to be parsed as HTML (Until told otherwise), then the @( ) forces its contents (The entire ? : expression as a whole) to be parsed as straight C#, then evaluated and returned, 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 18, 2014 2:48 PM
  • User583311198 posted

    Hi,

    As in your given resultset, MinutesFraction can have null value, you haven't checked null value for MinutesFraction before calling ToString() method on it. 

    The code should be like this: 

    grid.Column("MinutesFraction", "Minutes", format: @<text>@item.isCompleted ? (@item.MinutesFraction==null ? "" : @item.MinutesFraction.ToString("00")) : ""</text>)

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 18, 2014 2:50 PM
  • User938738290 posted

    Hm, I guess I just assumed that the point of item.IsCompleted was to do the null-checking, and that this was an issue with the Razor engine, and not with the use of the ? operator.  Maybe this was a bad assumption, I'm sure OP will let us know.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 18, 2014 2:54 PM

All replies

  • User-821857111 posted

    The binding error is caused by the ToString("00") call on a null reference. It seems that is evaluated regardless. You need to test to see if item.MinutesFraction is null before you attempt to perform any string operations on it. You can nest conditional operations:

    format: @<text>@item.isCompleted ? item.MinutesFraction != null ? @item.MinutesFraction.ToString("00") : "" : ""</text>

    Wednesday, July 16, 2014 2:14 AM
  • User379720387 posted

    Not having much luck getting this to work. I have dropped item.isCompleted to simplify.

    MinutesFraction is the result of a substraction between ttInStamp and ttOutStamp, the column as such does not exist in one of the table, just in the query.

    grid.Column("MinutesFraction", "Minutes", format: @<text>@item.MinutesFraction != null ? @item.MinutesFraction.ToString("00") : "" </text>)

    And the error message:

    Line 241:                
    Line 242:                grid.Column("Hours", "Hours"),
    Line 243:                grid.Column("MinutesFraction", "Minutes", format: @<text>@item.MinutesFraction != null ? @item.MinutesFraction.ToString("00") : "" </text>)
    Line 244:                
    Line 245:                ),


    Source File: c:\Users\robert\My Websites\bt\Members\TimeTrackerM.cshtml    Line: 243

    Stack Trace:

    [RuntimeBinderException: Cannot perform runtime binding on a null reference]

    Friday, July 18, 2014 2:12 PM
  • User938738290 posted

    I think the original issue is that the left side of the unary ? consists of:

    @item.isCompleted

    Which, because of the @, is going to return a HelperResult, not a bool.  It may evaluate to true when the compiler forces it to bool, which means that this the ToString( ) call may be getting executed regardless of the actual value of item.isComplete.

    Try this:

    grid.Column("MinutesFraction", "Minutes", format: @<text>@(item.isCompleted ? item.MinutesFraction.ToString("00") : "")</text>)

    The @<text> forces everything between it and the </text> to be parsed as HTML (Until told otherwise), then the @( ) forces its contents (The entire ? : expression as a whole) to be parsed as straight C#, then evaluated and returned, 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 18, 2014 2:48 PM
  • User583311198 posted

    Hi,

    As in your given resultset, MinutesFraction can have null value, you haven't checked null value for MinutesFraction before calling ToString() method on it. 

    The code should be like this: 

    grid.Column("MinutesFraction", "Minutes", format: @<text>@item.isCompleted ? (@item.MinutesFraction==null ? "" : @item.MinutesFraction.ToString("00")) : ""</text>)

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 18, 2014 2:50 PM
  • User938738290 posted

    Hm, I guess I just assumed that the point of item.IsCompleted was to do the null-checking, and that this was an issue with the Razor engine, and not with the use of the ? operator.  Maybe this was a bad assumption, I'm sure OP will let us know.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, July 18, 2014 2:54 PM
  • User379720387 posted

    @emu42

    Correct, the only purpose of isCompleted is to allow for the NULL checking.

    Your solution worked.

    @SwastikMS

    Your solution did not work. Same error message.

    Friday, July 18, 2014 4:57 PM