Welcome to the Inedo Forums! Check out the Forums Guide for help getting started.

If you are experiencing any issues with the forum software, please visit the Contact Form on our website and let us know!

API expects null instead of 0 for integer values



  • I'm running into an interesting issue where the API seems to be unhappy when you pass a zero for an integer value instead of a null. For example, when creating a new feed, and passing the below JSON:

    {	
      "name": "internal-chocolatey",	
      "alternateNames": null,	
      "feedType": "chocolatey",	
      "description": null,	
      "active": true,	
      "cacheConnectors": true,	
      "dropPath": null,	
      "packagePath": null,	
      "packageStore": null,	
      "allowUnknownLicenses": true,	
      "allowedLicenses": null,	
      "blockedLicenses": null,	
      "symbolServerEnabled": false,	
      "stripSymbols": false,	
      "stripSource": false,	
      "connectors": null,	
      "vulnerabilitySources": null,	
      "retentionRules": [	
        {	
          "deletePrereleaseVersions": false,	
          "deleteCached": true,	
          "keepVersionsCount": 10,	
          "keepUsedWithinDays": 0,	
          "triggerDownloadCount": 0,	
          "keepPackageIds": null,	
          "deletePackageIds": null,	
          "keepVersions": null,	
          "deleteVersions": null,	
          "sizeTriggerKb": 102400,	
          "sizeExclusive": true	
        }	
      ],	
      "packageFilters": {},	
      "packageAccessRules": {},	
      "replication": {	
        "clientMode": null,	
        "serverMode": null,	
        "clientToken": null,	
        "serverToken": null,	
        "sourceUrl": null	
      },	
      "variables": {}	
    }
    

    Results in the following error:

    547160FeedRetentionRules_CreateOrUpdateRule37`The INSERT statement conflicted with the CHECK constraint "CK__FeedRetentionRules". The conflict occurred in database "ProGet", table "dbo.FeedRetentionRules", column 'TriggerDownload_Count'.

    Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.

    Notice that in the JSON above that the keepUsedWithinDays and triggerDownloadCount are both set to 0. This is what the API appears to be complaining about. If you replace those values with null like so:

    ...
    "retentionRules": [	
        {	
          "deletePrereleaseVersions": false,	
          "deleteCached": true,	
          "keepVersionsCount": 10,	
          "keepUsedWithinDays": null,	
          "triggerDownloadCount": null,	
          "keepPackageIds": null,	
          "deletePackageIds": null,	
          "keepVersions": null,	
          "deleteVersions": null,	
          "sizeTriggerKb": 102400,	
          "sizeExclusive": true	
        }	
      ],
    ...
    

    The API has no issues creating the new feed. This is problematic because, behind the scenes, the Powershell API I am developing has defined these two properties as integers and the "zero value" for them is 0, not null.

    The only option I have is to manually check for these edge cases and convert the zeroes into nulls before sending off the JSON which seems rather silly. Is there a specific reason the API won't accept a zero in this case?


  • inedo-engineer

    @joshuagilman_1054 said in API expects null instead of 0 for integer values:

    The only option I have is to manually check for these edge cases and convert the zeroes into nulls before sending off the JSON which seems rather silly. Is there a specific reason the API won't accept a zero in this case?

    Well, the specific reason is due to data integrity rules; the TriggerDownload_Count is just defined as a nullable, non-zero, positive integer. Using -1 would also yield the same error.

    And as a general practice, we don't convert user input to NULL, or add extra code to make it work in a case like yours -- we just let the data integrity rules raise errors like that.

    In our own code, we'll do what you do (and pass a zero or empty string around, for example); so in a case like that, we just have a function like NullIf(value,0) or Nullif(value,"") before attempting an internal API call. So that would probably be the best bet.



  • It presents an interesting case for Powershell specifically since it's not possible to set a property defined as an integer to the value $null. For example:

    class MyClass {
      [int] $myInt
    }
    
    $my_class = [MyClass]::new()
    $my_class.myInt # 0
    
    $my_class.myInt = $null
    $my_class.myInt # 0
    

    My Powershell is not very strong, but from what I'm seeing here, the only viable way to satisfy the data integrity rule is to remove the static typing on my end for these properties. Otherwise, I'd be resorting to some super hacky post-editing of the JSON because there's no case in which Powershell would output a JSON string with null for the value of a statically typed integer.


  • inedo-engineer

    @joshuagilman_1054 I don't really know PowerShell myself (today I learned you can do classes 😅)... but behind-the-scenes it's .NET, and that means we can use nullable value types.

    I tried [int?] (nullable shortcut syntax) and [Nullable<int>] (generics shortcut syntax) but PowerShell isn't so happy with either. So the long way it is...

    [System.Nullable``1[[System.Int32]]] $myInt = 0
    echo "myInt is $myInt "
    $myInt = $null
    echo "myInt is $myInt "
    $myInt = 1000
    echo "myInt is $myInt "
    

    That should do the trick for you, and is close to our JSON Model anyways.



  • That did it, thanks! TIL that nullable types were a thing :)


  • inedo-engineer

    @atripp @joshuagilman_1054

    TIL that PowerShell can use internal CLR generic reference type names like that! But really, please don't do that...

    • ⛔ [System.Nullable``1[[System.Int32]]]
    • 👍 [Nullable[int]]

    ... much easier to read 🤠


Log in to reply
 

Inedo Website HomeSupport HomeCode of ConductForums GuideDocumentation