EmiratesKit.Annotations
1.0.1
dotnet add package EmiratesKit.Annotations --version 1.0.1
NuGet\Install-Package EmiratesKit.Annotations -Version 1.0.1
<PackageReference Include="EmiratesKit.Annotations" Version="1.0.1" />
<PackageVersion Include="EmiratesKit.Annotations" Version="1.0.1" />
<PackageReference Include="EmiratesKit.Annotations" />
paket add EmiratesKit.Annotations --version 1.0.1
#r "nuget: EmiratesKit.Annotations, 1.0.1"
#:package EmiratesKit.Annotations@1.0.1
#addin nuget:?package=EmiratesKit.Annotations&version=1.0.1
#tool nuget:?package=EmiratesKit.Annotations&version=1.0.1
EmiratesKit.Annotations
DataAnnotation validation attributes for UAE documents. Decorates model properties with [EmiratesId], [UaeIban], [UaeTrn], [UaeMobile], and [UaePassport] to trigger automatic validation during ASP.NET Core model binding.
Depends on EmiratesKit.Core, which is installed automatically.
Installation
dotnet add package EmiratesKit.Annotations
EmiratesKit.Core is installed automatically as a dependency. You do not need to install it separately.
When to Use This Package
Use EmiratesKit.Annotations when you want validation to run automatically as part of ASP.NET Core model binding — without writing any validation logic in your controllers or services.
When a request arrives, ASP.NET Core binds the request body to your model, runs all validation attributes, and populates ModelState. If any attribute fails, [ApiController] returns a 400 Bad Request response automatically before your action method is ever called.
If you need more control — conditional validation, cross-field rules, or custom error messages per rule — use EmiratesKit.FluentValidation instead.
Available Attributes
| Attribute | Validates | Backed by |
|---|---|---|
[EmiratesId] |
Emirates ID in format 784-YYYY-NNNNNNN-C |
Luhn algorithm |
[UaeIban] |
UAE IBAN starting with AE, 23 characters |
Mod-97 algorithm |
[UaeTrn] |
15-digit TRN starting with 100 |
Structure check |
[UaeMobile] |
UAE mobile in any accepted format | Prefix lookup |
[UaePassport] |
1 uppercase letter + 7 digits | Regex pattern |
Basic Usage
Decorate your model properties with the relevant attribute:
using System.ComponentModel.DataAnnotations;
using EmiratesKit.Annotations.Attributes;
public class CreateCustomerRequest
{
[Required]
public string FullName { get; set; } = "";
[Required]
[EmiratesId]
public string EmiratesId { get; set; } = "";
[Required]
[UaeMobile]
public string Mobile { get; set; } = "";
[UaeIban]
public string? BankAccount { get; set; }
[UaeTrn]
public string? TaxRegistrationNumber { get; set; }
[UaePassport]
public string? PassportNumber { get; set; }
}
No changes are needed in the controller. With [ApiController], validation runs automatically:
[ApiController]
[Route("api/customers")]
public class CustomersController : ControllerBase
{
[HttpPost]
public IActionResult Create([FromBody] CreateCustomerRequest request)
{
// If EmiratesId or Mobile failed validation,
// ASP.NET Core already returned 400 before reaching here.
return Ok();
}
}
Custom Error Messages
Every attribute accepts a custom ErrorMessage:
[EmiratesId(ErrorMessage = "Emirates ID must be in the format 784-YYYY-NNNNNNN-C.")]
public string EmiratesId { get; set; } = "";
[UaeMobile(ErrorMessage = "Please enter a valid UAE mobile number (e.g. 050 123 4567).")]
public string Mobile { get; set; } = "";
[UaeIban(ErrorMessage = "Bank account must be a valid UAE IBAN starting with AE.")]
public string? BankAccount { get; set; }
[UaeTrn(ErrorMessage = "Tax Registration Number must be 15 digits starting with 100.")]
public string? TaxRegistrationNumber { get; set; }
[UaePassport(ErrorMessage = "Passport number must be one letter followed by 7 digits.")]
public string? PassportNumber { get; set; }
Null and Empty Behaviour
All attributes in this package treat null and empty string as passing. They only validate when a value is present.
This is consistent with how standard .NET attributes like [EmailAddress] and [Phone] behave.
To make a field required, combine the attribute with [Required]:
// Optional — only validated when a value is provided
[UaeIban]
public string? BankAccount { get; set; }
// Required — must be present and must be a valid Emirates ID
[Required]
[EmiratesId]
public string EmiratesId { get; set; } = "";
Validation Response Format
When a request fails model validation, ASP.NET Core returns a 400 Bad Request with a ValidationProblemDetails body:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"EmiratesId": [
"Emirates ID must be in the format 784-YYYY-NNNNNNN-C."
],
"Mobile": [
"Please enter a valid UAE mobile number."
]
}
}
The key in errors is the property name. The value is the list of error messages from the failing attributes.
Using with MVC and Razor Pages
The attributes work in all ASP.NET Core hosting models, not just Web API. For MVC controllers and Razor Pages, check ModelState.IsValid manually:
// MVC controller
[HttpPost]
public IActionResult Create(CreateCustomerRequest request)
{
if (!ModelState.IsValid)
return View(request);
// proceed
return RedirectToAction("Index");
}
// Razor Page
public IActionResult OnPost()
{
if (!ModelState.IsValid)
return Page();
// proceed
return RedirectToPage("Success");
}
Using with Manual Validation
If you are not using ASP.NET Core model binding, you can trigger attribute validation manually using Validator.TryValidateObject:
using System.ComponentModel.DataAnnotations;
var request = new CreateCustomerRequest
{
EmiratesId = "784-1990-0000000-0", // invalid checksum
Mobile = "+971501234567"
};
var context = new ValidationContext(request);
var results = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(request, context, results, validateAllProperties: true);
foreach (var result in results)
{
Console.WriteLine(result.ErrorMessage);
// Emirates ID checksum is invalid (Luhn algorithm failed).
}
Related Packages
| Package | Purpose |
|---|---|
| EmiratesKit.Core | Core validators, static API, dependency injection support |
| EmiratesKit.FluentValidation | FluentValidation rule extensions for complex validation scenarios |
License
MIT License. Copyright 2026 Akhil P Vijayan.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 was computed. 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. |
-
net6.0
- EmiratesKit.Core (>= 1.0.1)
-
net7.0
- EmiratesKit.Core (>= 1.0.1)
-
net8.0
- EmiratesKit.Core (>= 1.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1 | 84 | 2/21/2026 |