SafeCoder.CommonKit
Small, safe helpers for messy data.
Real-world data is messy. A form sends " U.S.A. " when you wanted "US". A database
holds 1900-01-01 because nobody knew the real date. An API sends "$1,299.99" where
you wanted a number. And one bad value in the wrong place can crash your whole app.
CommonKit takes those messy values and hands you clean, typed, safe ones — without ever crashing.
Get started Try the 15-minute tutorial
This site documents library version 1.3.1; the changelog says what each version brought.
using SafeCoder.CommonKit;
CkText.Name(" mary-jane smith "); // -> "Mary-Jane Smith"
CkMoney.Amount("$1,299.99"); // -> 1299.99m
CkCountry.Alpha2("U.S.A."); // -> "US"
CkDateTime.ToDateTimeOrNull("1900-01-01"); // -> null (a placeholder, not a real date)
CkEmail.Address("not an email"); // -> "" (rejected — but no crash)
The one promise
Nothing throws by default. Every method accepts anything — null, garbage text,
the wrong type, a ten-megabyte string — and answers with a calm, predictable value:
string methods answer "", converters answer your fallback, the …OrNull readers
answer null and never throw at all. Want an exception instead? Nearly every method
takes throwIfInvalid: true. Want the reason in words, for a form? Every class that
checks a value has an Explain. The full rules are on How it works.
What's inside
-
Text people type
Names, emails, phones, identity numbers, postal codes and countries — cleaned, checked, masked for display, and judged with a verdict for validation code.
-
Numbers, money, time and place
Every numeric type, yes-or-no values that keep "unknown" apart from "no", amounts with symbols, dates in every shape, coordinates with real math.
-
Straight off the wire
JSON, forms and query strings into one bag; typed values out of it; identifiers and network gates.
-
Honest storage
One call turns every placeholder — empty text, zeros,
1900-01-01— into a realNULLon the way to the database.
The pipeline
The classes are built to work as a chain, from the wire to the database:
wire text ──CkPayload──▶ dictionary ──CkDictionary──▶ typed values
──domain classes (CkEmail, CkMoney, CkDate, …)──▶ clean values
──CkSentinel.ToNull──▶ honest NULLs for storage
Follow one order through all of it in Your first payload — and see the whole handler it becomes at the end.
Start here
-
Getting started
From nothing to your first call: the SDK, the reference, the
usingline — and what you did not have to write. -
Your first payload
A hands-on tutorial: fifteen minutes from a messy order payload to clean, typed values — breaking it on purpose, and the whole handler at the end.
-
How it works
Five rules cover the whole library — and every read is one decision: the plain method, the
…OrNulltwin, orthrowIfInvalid: true. One table settles it. -
Common mistakes
The twelve traps everyone hits once — bare percents, "false" booleans, locale bugs — with the wrong and the right code side by side.
Guides
-
Writing a validator
Every problem with a payload at once, in the readers' own words — built on
Explain, no exception in sight. -
Taking a payment
A cart, a discount, tax, a charge, a receipt — with
CkMoneyon every line that touches an amount, and no silent zero. -
Using it with EF Core
Cleaning getters, one save hook for honest
NULLs, the query rules, and why text columns need a length. -
Using it with AI tools
Point Copilot, Claude or Cursor at the library's own instruction file and the code they write uses CommonKit properly.
Built to be trusted
- 10,563 tests run on every build, on .NET 8, 9 and 10 alike — a test class per
public method, and four suites that run every public method automatically: one with
hostile input to prove nothing throws, one against the library's promises (valid text
out, cleaning twice is cleaning once, a validator agrees with its reader, every call
bounded in time), one proving that a reader, its
Explain, its exception and its…OrNulltwin never disagree about a value, and one running every call under five foreign cultures to prove the answer never changes. - One dependency — TimeZoneConverter, for time-zone ids; the .NET base library and nothing else.
- Invariant everywhere — the same output on every machine, whatever its locale.
- Every result comment on this site is checked against the library's tests before it is published.