Matthew Hudson
Matthew Hudson

Reputation: 1316

Decimal? - Nullable object must have a value

I'm using VB.NET MVC 5.1 in VS2013 using Razor

siq.Price is a Decimal?

I'm trying to check if siq.Price has a value, and if so print it as a currency. I recieve this error when trying to access the .Value property for elements where true they returned true for .HasValue:

Nullable object must have a value.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Nullable object must have a value.

I tried both of these lines of code, believing they should work without issue, yet recieved the error above:

@IIf(siq.Price.HasValue, siq.Price.Value, "N/A")
   'and
@IIf(siq.Price.HasValue, siq.Price.Value.ToString("C"), "N/A")

As soon as I remove the .Value from the TruePart then it started working:

@IIf(siq.Price.HasValue, siq.Price, "N/A")
    'and
@IIf(siq.Price.HasValue, String.Format("{0:C}", siq.Price), "N/A")

Can anyone explain why this is happening?! I'm rather perplexed.

NOTE: This piece of code works on it's own if the Price has a value, but not in the IIf():

@siq.Price.Value.ToString("C")

Upvotes: 0

Views: 801

Answers (3)

Isha John
Isha John

Reputation: 623

IIf() runs both the true and false code. VB's conditional If operator is short-circuit so you can now safely write the following, which is not possible using the IIf function:

Dim len = If(text Is Nothing, 0, text.Length)

Upvotes: 0

Avner Shahar-Kashtan
Avner Shahar-Kashtan

Reputation: 14700

At first glance, VB.NET's IIf method seems equivalent to C#'s ternary operator (?:), but there's a big difference: because it's a method, not an operator, there's no short circuiting, and both parameters are always evaluated before being passed to the method.

What this means is that regardless of whether HasValue is true, both siq.Price.Value and "N/A" are evaluated, leading to the exception you saw.

Upvotes: 1

Rowland Shaw
Rowland Shaw

Reputation: 38130

The IIF() function in VB.Net always evaluates both the true and false parts. Instead, you should change to use the IF() operator, which only evaluates the return value, so something like:

@If(siq.Price.HasValue, siq.Price.Value.ToString("C"), "N/A")

Upvotes: 5

Related Questions