Search code examples
c#windows-phone-8.1boolean-logicinvalidoperationexceptionrelaycommand

How to resolve an InvalidOperationException on Bool condition?


I've set up a bool property to prevent or allow a command to fire based on that bool being set to true.

In the current implementation, I check within the bool that certain values are not null before setting the bool to true.

Question:

Why do I get an InvalidOperationException on the condition within the bool?

Overview of code:

Bool property CanSendCommand, which is used as a param in the Relay command below:

private bool CanSendCommand()
{
    if (SelectedParkDuration.Value != null && RegNumber != string.Empty && SelectedZone.ZoneName != null)
    {
        return true;
    }

    return false;
}

TagRequestCommand which is called initially in a load method on class initilization. The command itself is bound to a button press on the UI.

For context RegNumber is type string, SelectedParkingDuration is ?TimeSpan, and SelectedZone.ZoneName is a string within a property:

    private void LoadCommands()
    {
        TagRequestCommand = new RelayCommand(async () =>
        {
            await SendParkingTagSMSRequest();
        } ,CanSendCommand );
    }

I've copied the exception details, which tells me the values for the condition are null which should be okay as its handled in the bool condition. I see then that there is line pointing to a "Nullable object must have a value", which tells me maybe my Timespan property SelectedParkDuration should have a value. But I'm not sure how it can have a value before a value has been selected.

System.InvalidOperationException was unhandled by user code
  HResult=-2146233079
  Message=Nullable object must have a value.
  Source=mscorlib
  StackTrace:
       at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
       at System.Nullable`1.get_Value()
       at Parking_Tag_Picker_WRT.ViewModel.TagRequestViewModel.CanSendCommand()
  InnerException: 

Screenshot of the autos windows during runtime:

enter image description here


Solution

  • Simple code in Linqpad to reproduce the scenario you have suggested:

    void Main()
    {
        // Test.SelectedParkDuration = 5;
    
        var result = Test.SelectedParkDuration.Value; // Invalid operation exception with above line commented out
    
        result.Dump();
    }
    
    public class Test
    {
        public static int? SelectedParkDuration { get; set;}
    }
    

    if you want Test.SelectedParkDuration.Value; to be successful, then first assign, else it will be Null Reference exception, .Net prefers Invalid Operation Exception to suggest that usage is incorrect, else if you expect value to be Null then should not use the Value property.

    To make above code work comment out the line:

    // Test.SelectedParkDuration = 5;
    

    Check this link too