Allow string or number values for a property with JSON adaptor
I have a class using the JSON adaptor:
Class pbarton.test Extends (%RegisteredObject, %JSON.Adaptor)
{
Property Version As %String;
}
The Version property could be either a string or a number in the JSON source data. If it's a string, importing it will succeed. If it's a number, importing fails.
set t = ##class(pbarton.test).%New()
w t.%JSONImport({"Version": "3"})
1
zw t.%JSONImport({"Version": 3})
"0 "_$lb($lb(9406,"Version","class base",,,,,,,$lb(,"USER",$lb("e^%JSONImportInternal+16^pbarton.test.1^1","e^%JSONImport+12^%JSON.Adaptor.1^1","e^^^0"))))/* ERROR #9406: Unexpected format for value of field, Version, using class base mapping [e^%JSONImportInternal+16^pbarton.test.1^1 e^%JSONImport+12^%JSON.Adaptor.1^1 e^^^0:USER] */
Is there anything I can do to make the class resilient to either string or number formatted values in the imported JSON?
Product version: IRIS 2022.1
Discussion (1)2
Comments
Hi Pravin,
The following pattern could work for you. Override and add a callback with a single line edit. Then maintaining the custom logic in a supporting callback. Will need to track behavior changes for %JSONImport when upgrading.
Method OnJSONImport(%JSONObject As %Library.DynamicAbstractObject) { set %JSONObject.Version=""_%JSONObject.Version } /// %JSONImport imports JSON or dynamic object input into this object.<br> /// The input argument is either JSON as a string or stream, or a subclass of %DynamicAbstractObject.<br> /// mappingName is the name of the mapping to use for the import. The base mapping is represented by "" and is the default. Method %JSONImport(input, %mappingName As %String = "") As %Status [ ServerOnly = 1 ] { Try { Set sc=$$$OK New %JSONObject If $isobject(input),input.%IsA("%Library.DynamicAbstractObject") { // Already a dynamic object Set %JSONObject=input } Else { // A JSON stream or string Set %JSONObject=##class(%Library.DynamicAbstractObject).%FromJSON(input) } // Add callback Do ..OnJSONImport(%JSONObject) // Do the import now. Set sc=..%JSONImportInternal() } Catch ex { Set sc=ex.AsStatus() } Quit sc }