Ignixa.Validation 0.5.2

dotnet add package Ignixa.Validation --version 0.5.2
                    
NuGet\Install-Package Ignixa.Validation -Version 0.5.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ignixa.Validation" Version="0.5.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ignixa.Validation" Version="0.5.2" />
                    
Directory.Packages.props
<PackageReference Include="Ignixa.Validation" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ignixa.Validation --version 0.5.2
                    
#r "nuget: Ignixa.Validation, 0.5.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ignixa.Validation@0.5.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ignixa.Validation&version=0.5.2
                    
Install as a Cake Addin
#tool nuget:?package=Ignixa.Validation&version=0.5.2
                    
Install as a Cake Tool

Ignixa.Validation

FHIR validation system with four validation depth levels.

Architecture

Four Validation Depth Levels (ADR-2527):

Depth Checks Use Case
Minimal JSON structure, required fields CREATE/UPDATE (blocking), bulk ingestion
Compatibility + Cardinality, types (lenient URIs) Microsoft FHIR Server migration
Spec + Required terminology, absolute URIs CREATE/UPDATE (blocking)
Full + FHIRPath invariants, all bindings $validate (async), compliance testing

Quick Start

Profile-aware validation (IG support)

To validate a resource against an Implementation Guide profile declared in Resource.meta.profile, layer the IG package's profiles + ValueSets on top of the base spec and use ProfileAwareValidationSchemaResolver:

using Ignixa.PackageManagement.Infrastructure;
using Ignixa.Validation.Schema;
using Ignixa.Validation.Services;

// 1. Load an IG package via Ignixa.PackageManagement.
//    (See Ignixa.PackageManagement for NpmPackageLoader + PackageExtractor.)
//    extractedResources: IReadOnlyList<ExtractedResource>

// 2. Layer the IG profiles on top of the base spec.
var baseSchema = new R4CoreSchemaProvider();
var schemaProvider = new ProfileLayeredSchemaProvider(baseSchema, extractedResources);

// 3. Layer the IG ValueSets on top of the base spec terminology.
var packageVs = new PackageValueSetSource(extractedResources);
var terminology = new InMemoryTerminologyService(
    primary: baseSchema.ValueSetProvider,
    additional: new[] { (IValueSetProvider)packageVs });

// 4. Build the resolver chain.
var inner = new StructureDefinitionSchemaResolver(schemaProvider, terminologyService: terminology);
var cached = new CachedValidationSchemaResolver(inner);
var profileAware = new ProfileAwareValidationSchemaResolver(cached);

// 5. Resolve a schema that composes base + every profile declared in meta.profile.
var element = sourceNode.ToElement(schemaProvider);
var schema = profileAware.ResolveForElement(element);

// 6. Validate.
var settings = new ValidationSettings { Depth = ValidationDepth.Spec };
var result = schema!.Validate(element, settings, new ValidationState());

ProfileAwareValidationSchemaResolver also implements IValidationSchemaResolver, so it's a drop-in for any DI registration that previously bound the cached resolver. The production ValidationServicesRegistration wires it automatically; consumers that have access to the resource element should call ResolveForElement(element) to pick up meta.profile composition.

CLI

The ignixa-validator CLI exposes profile-aware validation directly:

ignixa-validator r4 \
  --input patient.json \
  --package hl7.fhir.us.core@6.1.0 \
  --depth spec \
  --console

--package id@version is repeatable; multiple packages are layered in declared order (later wins on profile id collisions). Packages are cached under %TEMP%/ignixa-validator-package-cache.

using Ignixa.Validation.Schema;
using Ignixa.Specification.Generated;
using Ignixa.Serialization;

// 1. Get FHIR schema for your version (R4, R4B, R5, or STU3)
var fhirSchema = new R4CoreSchemaProvider();

// 2. Get the type definition for the resource you want to validate
var patientType = fhirSchema.GetTypeDefinition("Patient");

// 3. Build validation schema (automatically creates all checks from StructureDefinition)
var builder = new StructureDefinitionSchemaBuilder();
var validationSchema = builder.BuildSchema(patientType!, fhirSchema);

// 4. Parse and validate your FHIR resource
var json = "{\"resourceType\":\"Patient\",\"id\":\"123\"}";
var sourceNode = JsonSourceNodeFactory.Parse(json).ToSourceNode();
var element = sourceNode.ToElement(fhirSchema);

// 5. Choose validation depth
var settings = new ValidationSettings { Depth = ValidationDepth.Spec };
var state = new ValidationState();
var result = validationSchema.Validate(element, settings, state);

if (!result.IsValid)
{
    var operationOutcome = result.ToOperationOutcome();
    // Return operationOutcome to client
}

Validating Different Resource Types

using Ignixa.Validation.Schema;
using Ignixa.Specification.Generated;
using Ignixa.Serialization;

var fhirSchema = new R4CoreSchemaProvider();
var builder = new StructureDefinitionSchemaBuilder();

// Validate Observation
var observationType = fhirSchema.GetTypeDefinition("Observation");
var observationSchema = builder.BuildSchema(observationType!, fhirSchema);

var observationJson = "{\"resourceType\":\"Observation\",\"status\":\"final\",\"code\":{}}";
var sourceNode = JsonSourceNodeFactory.Parse(observationJson).ToSourceNode();
var result = observationSchema.Validate(sourceNode.ToElement(fhirSchema));

Validation Depth Guide

Minimal

Fastest validation for high-throughput scenarios:

var settings = new ValidationSettings { Depth = ValidationDepth.Minimal };

Compatibility

For migrating from Microsoft FHIR Server (Firely SDK validation):

var settings = new ValidationSettings { Depth = ValidationDepth.Compatibility };
  • Accepts relative URIs in Coding.system (e.g., "internal-tags")
  • Same checks as Spec, but more lenient for migration scenarios
  • Use when running Microsoft FHIR Server E2E test suite

Spec

Standard FHIR specification compliance:

var settings = new ValidationSettings { Depth = ValidationDepth.Spec };
  • Enforces absolute URIs in Coding.system
  • Required terminology bindings
  • Recommended for production API operations

Full

Complete FHIR profile validation:

var settings = new ValidationSettings { Depth = ValidationDepth.Full };
  • All Spec checks plus FHIRPath invariants
  • Extensible terminology bindings
  • Use for compliance testing and profile conformance

What Gets Validated

When you use StructureDefinitionSchemaBuilder, it automatically extracts and creates validation checks from FHIR StructureDefinition metadata. Here's what gets checked:

Tier 1 (Fast) - Universal Checks

These checks run for every CREATE/UPDATE operation:

Check Purpose When Applied
JsonStructureCheck Validates JSON is well-formed object with resourceType Resources only
NarrativeCheck Validates Narrative.status and Narrative.div Resources only
CardinalityCheck Validates min/max element count (0..1, 1..1, 0.., 1..) All elements except xhtml
TypeCheck Validates primitive types (id, string, integer, boolean, etc.) All primitive elements

Tier 2 (Spec) - Schema-Driven Checks

Additional checks extracted from StructureDefinition metadata:

Check Purpose When Applied
ReferenceFormatCheck Validates Reference.reference format (relative/literal/url) Elements with type=Reference
CodingStructureCheck Validates Coding.system + Coding.code structure Elements with type=Coding or CodeableConcept
ChoiceElementCheck Validates choice elements (only one variant present) Elements with name ending in [x]
ExtensionStructureCheck Validates Extension.url is present and value/extension rules Elements named "extension"
FixedValueCheck Validates element has exact fixed value Elements with fixedValue constraint
PatternCheck Validates element matches pattern constraint Elements with patternValue constraint
BindingCheck Validates coded values against built-in, required ValueSets Elements with binding
NestedComplexTypeCheck Validates nested BackboneElement and complex types BackboneElement children
UnknownPropertyCheck Rejects unknown/undefined properties All resources
FhirPathInvariantCheck Validates FHIRPath constraints (ele-1, dom-1, custom invariants) Elements with constraint definitions

Tier 3 (Profile) - Slicing, advanced terminology

Profile validation against Implementation Guide profiles declared in Resource.meta.profile. See the Profile-aware validation section above for the wiring.

Check Purpose When Applied
FhirPathInvariantCheck Validates FHIRPath constraints from IG profiles (e.g. CARIN-BB EOB-inst-careTeam-practitioner) Profile elements with constraint definitions
BindingCheck Validates coded values against IG ValueSets (e.g. US Core us-core-birthsex) Profile elements with binding (requires ITerminologyService layered with PackageValueSetSource)
CardinalityCheck Enforces tightened cardinality from profile elements (e.g. US Core Patient.identifier min=1) Profile elements with stricter min/max
FixedValueCheck / PatternCheck Enforces fixed/pattern values from profile elements Profile elements with fixed/pattern constraints

Currently unsupported (out of scope): discriminator-based slicing (e.g. CARIN-BB adjudication-has-amount-type-slice). Slice members in the snapshot are deduped to the slice header so the validator emits the correct base cardinality; per-slice constraints are silently ignored. Tracked for a future iteration.

License

MIT License - see LICENSE file in repository root

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Ignixa.Validation:

Package Downloads
Ignixa.DeId

FHIR data de-identification library supporting R4, R4B, R5, R6, and STU3 via Ignixa SDK

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.5.2 0 6/16/2026
0.5.0 27 6/15/2026
0.0.163 276 2/11/2026
0.0.160 133 2/9/2026
0.0.155 139 1/24/2026
0.0.151 127 1/21/2026
0.0.150 127 1/20/2026
0.0.149 113 1/19/2026
0.0.148 120 1/18/2026
0.0.142 122 1/12/2026
0.0.137 169 1/9/2026
0.0.127 163 12/29/2025
0.0.109 321 12/18/2025
0.0.101 309 12/16/2025
0.0.96 450 12/10/2025
0.0.87 458 12/8/2025
0.0.70 335 12/7/2025
0.0.68 260 12/7/2025
0.0.62 261 12/6/2025
0.0.59 206 12/5/2025
Loading failed