AstrolUI AstrolUI
Yellow Orange Red Green Blue Purple Custom color
Light mode
.NET extensions

Astrol.Entities.Basic: extension methods for text, numbers, dates, AstrolGrid queries, colors, enums and JSON.

Astrol.Entities.Basic is installed with Astrol.Component.Basic and brings extension methods for what almost every app repeats: cleaning and searching text, showing amounts and dates, paging on the server or picking a readable text color. They all accept null and never throw on an empty value. They are plain C#: they work the same in Blazor, an API or a service.

@* Installed with Astrol.Component.Basic (package Astrol.Entities.Basic) *@
@using Astrol.Entities.Basic.Static.Extensions
@using Astrol.Entities.Basic.Static @* Auxiliar.NewKey(), Auxiliar.NewDomId() *@

1. Text

ToSearchKey lowercases the text, removes accents and ñ and leaves a single space between words: compare two keys and search works whether the user types «configuracion» or «CONFIGURACIÓN» (AstrolComboBox uses it this way). ContainsIgnoreAccents does it in one call. There are also URL slugs, avatar initials, title-cased names, truncation with «…», email and file-extension validation.

Type in the demo to see the result of each method.

ToSearchKey() asley fernandez cruz — configuracion ToSlug() asley-fernandez-cruz-configuracion ToTitleCase() Asley Fernández Cruz — Configuración GetInitials() AC Truncate(18) Asley Fernánd… RemoveDiacritics() Asley Fernandez Cruz — Configuracion IsValidEmail() False
// Search without accents or case (filters, combos, lists)
var term = search.ToSearchKey(); // " Árbol " -> "arbol"
var result = clients.Where(c => c.Name.ContainsIgnoreAccents(search));
 
string slug = "¡Hola, Año 2026!".ToSlug(); // "hola-ano-2026"
string name = "jUAN pérez".ToTitleCase(); // "Juan Pérez"
string avatar = user.FullName.GetInitials(); // "AC"
string preview = article.Body.RemoveHtmlTags().Truncate(120);
string phone = "5512345678".FormatPhoneNumber(); // "(551) 234 5678"
string label = user.Nickname.IfEmpty("(no name)");
 
bool ok = email.IsValidEmail();
bool allowed = file.Name.IsAllowedExtension(new[] { ".pdf", ".png" });
string tags = product.Tags.JoinText(", "); // skips null / empty

2. Numbers, money and sizes

ToMoney uses the currency format of the current culture (right separators and symbol in es-MX, en-US, es-ES...) and can append the currency code. ToCompact shortens large figures for cards and charts. PercentOf returns 0 when the total is 0, with no division by zero. ToFileSize shows a file size in the right unit.

ToMoney() ¤1,234,567.89 ToMoney("MXN") ¤1,234,567.89 MXN ToCompact() 1.2M ApplyPercent(16) 197530.86 PercentOf(10000) 12345.68 % ((long)n).ToFileSize() 1.2 MB
string price = 1234.5m.ToMoney(); // "$1,234.50" (current culture)
string mxn = 1234.5m.ToMoney("MXN"); // "$1,234.50 MXN"
string visits = 3_400_000L.ToCompact(); // "3.4M" (cards and charts)
 
decimal tax = subtotal.ApplyPercent(16); // 16 % of the subtotal
decimal progress = done.PercentOf(total); // 0 when total is 0
 
string size = file.Size.ToFileSize(); // "1.5 MB"
long max = 5L.ToBytes(TypeStorage.Megabyte); // 5 242 880

3. Dates

ToRelativeTime writes «hace 5 minutos» or «5 minutes ago» depending on the app language; a UTC date is compared with UTC time. ToDisplay formats dates that may be null (it returns an empty string) and can convert them to local time first. Start and end of day, week and month make range filters simple, and EndOfDay includes the whole last day.

-40 s just now -5 min 5 minutes ago -3 h 3 hours ago +2 d in 2 days -14 m 1 year ago ToDisplay() 10/24/2026 2:59 PM ToDisplay("D") Saturday, October 24, 2026 StartOfWeek() 10/19/2026 EndOfMonth() 10/31/2026
string when = comment.CreatedAt.ToRelativeTime(); // "hace 5 minutos" / "5 minutes ago"
string text = order.Date.ToDisplay(); // "24/10/2026 12:00" ("" if null)
string local = order.DateUtc.ToDisplay("g", toLocalTime: true);
 
// Date range filters
var from = DateTime.Today.StartOfMonth();
var to = DateTime.Today.EndOfDay();
var orders = db.Orders.Where(o => o.Date >= from && o.Date <= to);
 
int age = client.BirthDate.GetAge();
bool weekend = DateTime.Today.IsWeekend();

4. Queries for AstrolGrid

For the table in server mode: SortList sorts by the column the table asks for (also nested paths such as «Client.Name») by building an expression EF Core translates to SQL; Paginate takes the requested page and ToPaginatedResponse does all three (sort, count and page) and returns what AstrolGrid expects. WhereIf applies a filter only when the user filled it in. With async EF Core, combine SortList and Paginate with CountAsync and ToListAsync.

// AstrolGrid in server mode: optional filters + sort + count + page
private async Task ReadItems(GridResponse<Client> request)
{
 var query = db.Clients
 .WhereIf(onlyActive, c => c.Active)
 .WhereIf(search.HasValue(), c => c.Name.Contains(search!));
 
 request.AstrolPaginatedResponse = query.ToPaginatedResponse(request.GridInfo);
}
 
// Async EF Core: the same steps by hand
var sorted = query.SortList(request.GridInfo.SortInfo); // x => x.Name, nested "Client.Name"
request.AstrolPaginatedResponse = new()
{
 TotalItems = await query.CountAsync(),
 PageItems = await sorted.Paginate(request.GridInfo).ToListAsync(),
};

5. Colors

GetColorContrast picks the text color (white or dark, or the ones you pass) with the most contrast on a background, using the WCAG formula: handy for tags or cards with a user-chosen color. GetContrastRatio gives the contrast ratio (4.5 is the AA minimum for normal text) and IsHexColor / NormalizeHexColor validate and normalize what is typed in a color field.

AstrolUI
GetColorContrast() #222222 GetContrastRatio("#fff") 1.53 GetContrastRatio("#222") 10.39
@* Readable text on a color chosen by the user *@
<span style="background:@tag.Color; color:@tag.Color.GetColorContrast()">@tag.Name</span>
 
@code {
 bool valid = input.IsHexColor(); // #rgb, #rrggbb, with or without #
 string? hex = "FA0".NormalizeHexColor(); // "#ffaa00"
 double ratio = "#facc15".GetContrastRatio("#222"); // >= 4.5: WCAG AA for text
}

6. Enums, JSON, collections and copies

GetDisplayName reads [Display(Name)] or [Description] from an enum value and ToSelectList turns the enum into options for a combo. DeepClone makes an independent copy (to edit in a modal and be able to cancel). ToJson / FromJson use System.Text.Json with the web options, and FromJson returns default when the text is not valid.

public enum OrderStatus
{
 [Display(Name = "Pending payment")] Pending,
 [Description("Shipped")] Shipped,
 Delivered,
}
 
string text = order.Status.GetDisplayName(); // "Pending payment"
List<SelectList<OrderStatus>> options = EnumExtensions.ToSelectList<OrderStatus>(); // for an AstrolComboBox
 
// Edit a copy in a modal and discard it on Cancel
var draft = client.DeepClone();
 
string json = filters.ToJson(); // camelCase
var filters = json.FromJson<Filters>(); // default if empty or invalid
 
if (items.IsNullOrEmpty()) { /* ... */ }
foreach (var item in maybeNull.OrEmpty()) { /* ... */ }
 
string key = Auxiliar.NewKey(32); // random alphanumeric key
string id = Auxiliar.NewDomId(); // "aui-k3f9x2" for label for="..."

Reference

Text (StringExtensions)

  • HasValue(), IfEmpty(fallback), Truncate(max, ellipsis)
  • ToSearchKey(), ContainsIgnoreAccents(term), RemoveDiacritics(keepEnye)
  • RemoveWhitespace(), CollapseWhitespace(), RemoveHtmlTags()
  • ToTitleCase(culture), Capitalize(), ToSlug(maxLength), GetInitials(max)
  • DigitsOnly(), FormatPhoneNumber(), IsValidEmail()
  • IsAllowedExtension(extensions), JoinText(separator, skipEmpty)
  • Obfuscate(key) / Deobfuscate(key): the browser storage obfuscation; it is not encryption.

Numbers and sizes (NumberExtensions, FileSizeExtensions)

  • PercentOf(total, decimals), ApplyPercent(percent, decimals)
  • ToMoney(currencyCode, culture, decimals), ToCompact(decimals, culture)
  • ToFileSize(decimals), ToKilobytes(), ToMegabytes(), ToBytes(TypeStorage)

Dates (DateExtensions)

  • ToDisplay(format, toLocalTime, culture) for DateTime, DateTimeOffset and their nullable versions
  • ToRelativeTime(now, culture)
  • StartOfDay(), EndOfDay(), StartOfWeek(firstDay), StartOfMonth(), EndOfMonth(), IsWeekend(), GetAge(today)

Queries and collections (AstrolQueryableExtensions, CollectionExtensions)

  • SortList(SortInfo | json), Paginate(GridInfo), WhereIf(condition, predicate), ToPaginatedResponse(GridInfo)
  • IsNullOrEmpty(), HasItems(), OrEmpty(), WhereIf for IEnumerable

Colors, enums, JSON and copies

  • GetColorContrast(light, dark), GetContrastRatio(other), IsHexColor(), NormalizeHexColor()
  • GetDisplayName(), EnumExtensions.ToSelectList<TEnum>()
  • ToJson(indented), FromJson<T>()
  • DeepClone()
  • Auxiliar.NewKey(length), Auxiliar.NewDomId(prefix)

The style extensions (GetButtonStyle, GetBoxStyle, GetThemeColor...) are used internally by the components.

Markdown for AI © 2026 AstrolUI v10.0.13