Canonical Hashing
The apiHash provides a deterministic fingerprint of the API surface.
Included in Hash
Section titled “Included in Hash”- Public types and members with signatures
- Parameter names, types, nullability
- Shape-affecting attributes (
[Obsolete],[Flags],[JsonDerivedType]) - JSON serialization metadata
ApiContractAttributemetadata- XML documentation text (summary, remarks, params, returns)
Excluded from Hash
Section titled “Excluded from Hash”- File paths, timestamps, build metadata
- Code sample content
- Ordering differences (canonical sorting applied)
- Whitespace and formatting
Process
Section titled “Process”- Build canonical model from public types/members
- Sort by namespace → type → member kind → name
- Serialize to UTF-8 JSON with sorted properties, no whitespace
- Hash with SHA-256
- Format as
sha256:<lowercase-hex>
Verification
Section titled “Verification”using ApiContracts.Verification;
// Validate schema structure and hash formatvar result = SchemaVerifier.ValidateSchema(schemaJson);
// Compute a hash from canonical JSONvar hash = SchemaVerifier.ComputeApiHash(canonicalJson);
// Verify the declared apiHash matches the types in the schemavar hashResult = SchemaVerifier.VerifyApiHash(schemaJson);if (!hashResult.IsMatch) Console.WriteLine($"Hash mismatch: declared={hashResult.DeclaredHash}, computed={hashResult.ComputedHash}");