Türkçe: README.TR.md · Documentation: herokit.lyconiq.com
HeroKit is a set of .NET libraries for two jobs:
- Turkish data, done right. TCKN, VKN and IBAN validation with bank lookup, phone numbers, vehicle plates, provinces and districts, public holidays and business days (half days included), amounts in words and e-invoice numbers. Everything runs on one
Country,LanguageandCurrencymodel, so other countries plug in the same way. - Safe file uploads. HeroKit.FileTypes detects the real file type from its content and rejects renamed executables, hidden double extensions (
a.php.jpg), script in SVG and macros in Office files. It has no dependencies and works on its own.
The core package also has everyday extension methods for strings, conversions, dates, collections and prices.
| Package | For |
|---|---|
| HeroKit | Turkish data, the country model and the extension methods |
| HeroKit.FileTypes | File type detection and safe upload checks, no dependencies |
| HeroKit.FileTypes.AspNetCore | IFormFile checks, [AllowedFileTypes], a minimal API filter |
| HeroKit.FluentValidation | FluentValidation rules for all of the above |
dotnet add package HeroKitTargets .NET 8 and .NET 10. No dependencies. Nullable-annotated and Native AOT ready (compiled ahead of time to a fast-starting native app).
using HeroKit.Banking;
using HeroKit.Globalization;
using HeroKit.Globalization.Turkey;
"10000000146".IsValidTckn(); // true (T.C. Kimlik No)
"4840847211".IsValidVkn(); // true (Vergi Kimlik No)
"TR330006100519786457841326".FormatIban(); // "TR33 0006 1005 1978 6457 8413 26"
"TR78 0006 2000 0000 0006 2950 05".GetBank()?.Name; // "Türkiye Garanti Bankası A.Ş."
"0532 123 45 67".ToE164(Countries.Turkey); // "+905321234567"
"34abc123".FormatVehiclePlate(Countries.Turkey); // "34 ABC 123"
Countries.Turkey.FindRegion("34")?.Name; // "İstanbul"
"34710".IsValidPostalCode(Countries.Turkey); // true
123.50m.ToCurrencyWords(Currencies.TurkishLira); // "yüz yirmi üç Türk lirası elli kuruş"
1234.5m.ToCurrencyString(Currencies.TurkishLira); // "₺1.234,50"
"₺1.234,56".ToAmount(Currencies.TurkishLira); // 1234.56
"10000000146".MaskMiddle(2, 2); // "10*******46" (KVKK)
Countries.Turkey.FindDistrict("istanbul", "kadikoy")?.Name; // "Kadıköy" (973 ilçe)
Tckn.Parse("10000000146").ToMaskedString(); // validated value type: "10*******46"
"istanbul ılıca".ToTitleCase(Languages.Turkish); // "İstanbul Ilıca"
new DateOnly(2026, 3, 19).AddBusinessDays(1, Countries.Turkey); // 2026-03-23 (skips the bayram and the weekend)
"ABC2026000000001".IsValidGibInvoiceNumber(); // true (e-Fatura / e-Arşiv)Every method takes a Country, Language or Currency. Türkiye and the United States are built in (Countries.UnitedStates: NANP phone numbers, ZIP codes, SSN/EIN, federal holidays, states, Currencies.USDollar, Languages.English). To support another country, implement the rule interfaces and call Countries.Register(new Country(...) { PhoneNumbers = ... }): no new methods are needed. Turkish sorting also works without ICU: names.OrderBy(n => n, Languages.Turkish.TextRules!.Comparer).
using HeroKit.Validation;
public sealed class Customer
{
[Required, Tckn] public string? IdentityNumber { get; set; }
[Iban] public string? Iban { get; set; }
[PhoneNumber("TR", MobileOnly = true)] public string? Mobile { get; set; }
[VehiclePlate("TR")] public string? Plate { get; set; }
}Also: [Vkn], [TaxId("TR")], [NationalId("TR")], [PostalCode("TR")], [GibInvoiceNumber], [Ettn], [CardNumber]. They work with ASP.NET Core, Blazor and Validator.
Using FluentValidation? Add HeroKit.FluentValidation: RuleFor(x => x.IdentityNumber).Tckn();
HeroKit.FileTypes is a separate, dependency-free package: content detection for about 70 types (Office inside ZIP, HEIC/AVIF/MP4 brands, WebP, JPEG XL), extension and MIME mapping, and an OWASP-style upload check.
using HeroKit.FileTypes;
FileTypes.Detect(stream)?.MimeType; // "image/png"
FileTypes.GetMimeType("report.docx"); // "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
FileTypes.CheckUpload(stream, "photo.php.jpg").Rejection; // UploadRejection.DoubleExtensionFor ASP.NET Core, HeroKit.FileTypes.AspNetCore checks IFormFile uploads: a ValidateUploads() endpoint filter for minimal APIs and an [AllowedFileTypes("jpg", "png")] attribute for MVC, Razor Pages and Blazor.
A runnable ASP.NET Core sample with uploads, Tckn binding and districts: samples/HeroKit.Samples.WebApi.
Every conversion has a lenient form that returns a default value and a Try form. Neither throws for bad input. Parsing is culture-invariant unless you pass a provider.
using HeroKit.Strings;
"42".ToInt(); // 42
"abc".ToInt(-1); // -1
"2026-03-07".To<DateOnly>(); // any IParsable<T>
"42".TryTo(out int number); // true
"1.234,56".ToDecimal(); // 1234.56
"Friday".ToEnum<DayOfWeek>(); // DayOfWeek.Friday| Area | Examples |
|---|---|
| Strings | ToSlug, Truncate, Mask, Left/Right, RemoveWhitespace, ToTitleCase(culture) |
| Collections | IsNullOrEmpty, WhereIf and Page (also on IQueryable), ToReadOnlyList |
| Dates | StartOfWeek, EndOfMonth, IsWeekend, IsBetween, Age (DateTime and DateOnly) |
| Prices | RoundToStep, ToPsychologicalPrice, IncludeVat, ExcludeVat |
| Cards | IsValidCardNumber (Luhn), GetCardBrand (incl. Troy) |
| Enums | GetDescription, ToEnum, ToUnderlying<T> |
The guides and API reference cover every method. Upgrading from 1.x or 2.x? See the upgrade guide.
- Questions and ideas: GitHub Discussions
- Bugs and feature requests: Issues
- How to contribute: CONTRIBUTING.md
MIT