PosInformatique.Foundations.PhoneNumbers
1.0.0
Prefix Reserved
See the version list below for details.
dotnet add package PosInformatique.Foundations.PhoneNumbers --version 1.0.0
NuGet\Install-Package PosInformatique.Foundations.PhoneNumbers -Version 1.0.0
<PackageReference Include="PosInformatique.Foundations.PhoneNumbers" Version="1.0.0" />
<PackageVersion Include="PosInformatique.Foundations.PhoneNumbers" Version="1.0.0" />
<PackageReference Include="PosInformatique.Foundations.PhoneNumbers" />
paket add PosInformatique.Foundations.PhoneNumbers --version 1.0.0
#r "nuget: PosInformatique.Foundations.PhoneNumbers, 1.0.0"
#:package PosInformatique.Foundations.PhoneNumbers@1.0.0
#addin nuget:?package=PosInformatique.Foundations.PhoneNumbers&version=1.0.0
#tool nuget:?package=PosInformatique.Foundations.PhoneNumbers&version=1.0.0
PosInformatique.Foundations.PhoneNumbers
Introduction
This package provides a strongly-typed PhoneNumber value object that represents a phone number in E.164 format.
It centralizes validation, parsing, comparison and formatting logic for phone numbers, and ensures that only valid international phone numbers can be instantiated.
It is recommended to use E.164 format everywhere in your code. When parsing a local phone number (not already in E.164), you must explicitly specify the region to avoid ambiguity.
This library uses the libphonenumber-csharp library under the hood for parsing and formatting.
Install
You can install the package from NuGet:
dotnet add package PosInformatique.Foundations.PhoneNumbers
Features
- Strongly-typed phone number value object based on E.164 format
- Validation and parsing of international and local phone numbers
- Always stored and returned in E.164 format by default
- Implements
IEquatable<PhoneNumber>for value-based equality - Implements
IFormattableandIParsable<PhoneNumber>for easy integration with .NET APIs (parsing/formatting) - Implicit conversion between
stringandPhoneNumber - Helpers to format in international and national formats
Use cases
- Validation: prevent invalid phone numbers from being stored in domain entities.
- Type safety: avoid handling raw strings for phone numbers across the application.
- Standardization: use E.164 format as the single source of truth everywhere.
- Integration: use
IParsable/IFormattablein generic components (bindings, configuration, serialization, etc.).
Examples
Create and validate phone numbers
using PosInformatique.Foundations.PhoneNumbers;
// Implicit conversion from string (expects a valid E.164 number)
PhoneNumber phone = "+33123456789";
// To string (E.164 by default)
Console.WriteLine(phone); // "+33123456789"
// Validation
var valid = PhoneNumber.IsValid("+33123456789"); // true
var invalid = PhoneNumber.IsValid("1234"); // false
Parsing E.164 phone numbers
var phone = PhoneNumber.Parse("+14155552671");
Console.WriteLine(phone); // "+14155552671"
Parsing local numbers with an explicit region
When you parse a local phone number (not starting with "+"), you must specify the region (ISO 3166-1 alpha-2, e.g. "FR", "US", ...).
// Local French number, region must be specified
var frenchPhone = PhoneNumber.Parse("01 23 45 67 89", defaultRegion: "FR");
Console.WriteLine(frenchPhone); // E.164: "+33123456789"
// TryParse with region
if (PhoneNumber.TryParse("06 12 34 56 78", out var mobile, defaultRegion: "FR"))
{
Console.WriteLine(mobile); // "+33612345678"
}
It is recommended to always work with E.164 numbers in your code (storage, comparison, APIs), and only handle local formats at the boundaries (UI, input parsing) by specifying the region explicitly.
Formatting: E.164, international and national
var phone = PhoneNumber.Parse("+14155552671");
// Default ToString() = E.164
Console.WriteLine(phone.ToString()); // "+14155552671"
// International format
Console.WriteLine(phone.ToInternationalString()); // "+1 415-555-2671" (example output)
// National format
Console.WriteLine(phone.ToNationalString()); // "(415) 555-2671" (example output)
Using implicit conversions
// string -> PhoneNumber (implicit)
PhoneNumber phone = "+447911123456";
// PhoneNumber -> string (implicit, E.164)
string phoneString = phone;
Console.WriteLine(phoneString); // "+447911123456"
Using IParsable<PhoneNumber> generically
Because PhoneNumber implements IParsable<PhoneNumber>, it can be used in generic parsing scenarios.
// Generic parsing using IParsable<T>
static T ParseValue<T>(string value)
where T : IParsable<T>
{
var result = T.Parse(value, provider: null);
return result;
}
var phone = ParseValue<PhoneNumber>("+33123456789");
Console.WriteLine(phone); // "+33123456789"
Using IFormattable generically
PhoneNumber also implements IFormattable, so it can be formatted via APIs that rely on IFormattable.
static string FormatValue(IFormattable value)
{
// format and provider are ignored in this implementation,
// but this allows generic handling of different value objects.
return value.ToString(format: null, formatProvider: null);
}
var phone = PhoneNumber.Parse("+33123456789");
var formatted = FormatValue(phone);
Console.WriteLine(formatted); // "+33123456789"
Recommendations
- Always store and exchange phone numbers in E.164 format (e.g. in your database, APIs, events).
- Only accept local phone numbers at the boundaries (UI, import, etc.), and always specify the
defaultRegionwhen parsing:PhoneNumber.Parse(localNumber, defaultRegion: "FR")PhoneNumber.TryParse(localNumber, out var number, defaultRegion: "FR")
- Avoid keeping raw strings. Use the
PhoneNumbervalue object everywhere to centralize validation and formatting.
Links
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. 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 was computed. 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. |
-
net8.0
- libphonenumber-csharp (>= 9.0.1)
-
net9.0
- libphonenumber-csharp (>= 9.0.1)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on PosInformatique.Foundations.PhoneNumbers:
| Package | Downloads |
|---|---|
|
PosInformatique.Foundations.PhoneNumbers.FluentValidation
FluentValidation integration for the PhoneNumber value object, providing dedicated validators and rules to ensure E.164 compliant phone numbers. |
|
|
PosInformatique.Foundations.PhoneNumbers.Json
System.Text.Json converter for the PhoneNumber value object, enabling seamless serialization and deserialization of phone numbers in E.164 format. |
|
|
PosInformatique.Foundations.PhoneNumbers.EntityFramework
Entity Framework Core integration for the PhoneNumber value object, mapping it to a SQL PhoneNumber column type backed by VARCHAR(16) using a dedicated value converter. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.0-rc.2 | 45 | 1/26/2026 |
| 1.1.0-rc.1 | 44 | 1/23/2026 |
| 1.0.0 | 450 | 11/19/2025 |
| 1.0.0-rc.4 | 358 | 11/19/2025 |
| 1.0.0-rc.3 | 369 | 11/18/2025 |
| 1.0.0-rc.2 | 372 | 11/18/2025 |
| 1.0.0-rc.1 | 373 | 11/18/2025 |
1.0.0
- Initial release with strongly-typed PhoneNumber value object.