Deserialisation
From a string
using Clarotech.OpenEHR.RM.Json;
string json = /* … */;
var composition = OpenEhrJsonSerializer.Deserialize<Composition>(json);
Deserialize<T> returns T? — it returns null when the JSON token is null.
From a stream
// Synchronous (e.g. MemoryStream)
using var stream = File.OpenRead("vital-signs.json");
var composition = OpenEhrJsonSerializer.Deserialize<Composition>(stream);
// Asynchronous (e.g. HttpResponseMessage.Content)
using var response = await client.GetAsync(…);
await using var body = await response.Content.ReadAsStreamAsync();
var composition = await OpenEhrJsonSerializer.DeserializeAsync<Composition>(body);
Polymorphic type resolution
The _type discriminator field drives concrete-type resolution throughout the object
graph — you do not need to know the concrete type at the call site:
// A Composition whose content[] items may be Observation, Evaluation, etc.
var composition = OpenEhrJsonSerializer.Deserialize<Composition>(json);
foreach (var item in composition.Content)
{
switch (item)
{
case Observation obs:
Console.WriteLine($"Observation: {obs.Name.Value}");
break;
case Evaluation eval:
Console.WriteLine($"Evaluation: {eval.Name.Value}");
break;
}
}
Likewise for Element.Value, which resolves to the correct DvXxx class:
var element = /* … */;
if (element.Value is DvQuantity qty)
Console.WriteLine($"{qty.Magnitude} {qty.Units}");
Deserialising a Version<Composition>
var version = OpenEhrJsonSerializer.Deserialize<OriginalVersion<Composition>>(json);
var composition = version?.Data;
Deserialising an Ehr
var ehr = OpenEhrJsonSerializer.Deserialize<Ehr>(json);
Case sensitivity
The deserialiser is case-insensitive for property names
(PropertyNameCaseInsensitive = true), so JSON from CDRs that emit camelCase
(e.g. archetypeNodeId) is accepted without any configuration.
Using OpenEhrJsonOptions directly
// Reading from a Utf8JsonReader
var reader = new Utf8JsonReader(utf8Bytes);
var composition = JsonSerializer.Deserialize<Composition>(ref reader, OpenEhrJsonOptions.Default);
// Reading with custom options layered on top
var opts = new JsonSerializerOptions(OpenEhrJsonOptions.Default);
opts.Converters.Add(new MyExtensionConverter());
var composition = JsonSerializer.Deserialize<Composition>(json, opts);
Error handling
System.Text.Json throws JsonException on malformed JSON and NotSupportedException
when no converter is registered for the target type. A missing _type discriminator will
cause JsonException when deserialising into an abstract base type such as DataValue
or ContentItem.
try
{
var composition = OpenEhrJsonSerializer.Deserialize<Composition>(json);
}
catch (JsonException ex)
{
Console.Error.WriteLine($"Invalid openEHR JSON: {ex.Message}");
}