-
Notifications
You must be signed in to change notification settings - Fork 347
Attribute validation and Overflow
This table lists how overflow is "encoded" in the POCO model, and which validator will catch the error.
Kind of error | How encoded | Detected by(1) |
---|---|---|
Incorrect primitive value | Incorrect value is stored in primitive's ObjectValue | ValidateObjectValue() |
Expected primitive, got object | (Dynamic)object is stored in primitive's ObjectValue | ValidateObjectValue() |
Expected object, got primitive | Store in overflow, with correct type "attached" (2) | ValidateObject(3) |
Expected single, got array | Store in overflow, with correct type "attached" (2) | ValidateObject(3) |
Expected array, got single | Store in overflow, with correct type "attached" (2) | ValidateObject(3) |
Choice where no choice allowed | Added as unknown element to overflow | See Unknown element below |
Invalid choice type | Property (type of DataType) is set to the value | AllowedTypes attribute |
Unknown choice type | Property is set to a DynamicDataType value | AllowedTypes attribute |
Unknown resource type | Property is set to a DynamicResource value | AllowedTypes attribute (4) |
Unknown element | Store in overflow, with "no type" attached | ValidateObject(3) |
(1) The property's getter (except for JsonValue) also detects it, and throws. We still might need an unsafe marker to do this efficiently. The setter needs to detect invalid values to remove any entries from the overflow dictionary when a new value is set.
(2) This probably means the overflow needs to contain tuples or types which allow for a value + expected type.
(3) We need detection in ValidateObject for .NET attribute validation, and this will be used when someone "manually" sets the POCO to incorrect values, but for the parsers this is a bit too late. For them to be able to report errors with locations on the right property, they probably need to report errors themselves, preferably reusing functionality to report the same error and error text as will be reported from ValidateObject. This means that ValidateObject
should not report these errors if called from a Parser (otherwise we get duplicate messages), but that is easy, since all validation routines get passed in a ValidationContext
, from which it is obvious (or can be made obvious) that we're running in the context of a parser.
(4) Normally, nested resources are marked with [AllowedTypes(typeof(Hl7.Fhir.Model.Resource))]
, we should make sure that in that case we complain about finding a DynamicResource.
SetValue
currently looks like this:
public override Base SetValue(string key, object? value)
{
switch (key)
{
case "identifier":
Identifier = (List<Hl7.Fhir.Model.Identifier>?)value!;
return this;
We can see that calling SetValue
to something that requires overflow (= of the incorrect type), will throw an invalid cast exception. This needs to be changed so that IF the type is incorrect, we switch to the overflow. And of course, since we already have the correct type at hand, we could store it in the overflow as well. Also, if we are using pairs in the dictionary, we have to make sure Copy, IsExact, Matches, Compare etc keep on working, cause they currently expect just Base/List in the overflow dictionary. It should also (just like normal setters, see remark (1)), make sure that updating a property to a new value removes/updates the entry in the overflow as well.