Reputation: 1316
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
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
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
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