maui-accessibility
Guide for making .NET MAUI apps accessible — screen reader support via SemanticProperties, heading levels, AutomationProperties…
Guidance for consuming REST APIs in .NET MAUI apps. Covers HttpClient setup with System.Text.Json, DI registration, service interface/implementation pattern, full CRUD operations (GET, POST, PUT, DELETE), error handling, platform-specific clear-text traffic configuration, and
$ npx -y skills add davidortinau/maui-skills --skill maui-rest-api --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/maui-rest-apiContext preview
The summary Claude sees to decide when to auto-load this skill.
Guidance for consuming REST APIs in .NET MAUI apps. Covers HttpClient setup with System.Text.Json, DI registration, service interface/implementation pattern, full CRUD operations (GET, POST, PUT, DELETE), error handling, platform-specific clear-text traffic configuration, and
name: maui-rest-api description: > Guidance for consuming REST APIs in .NET MAUI apps. Covers HttpClient setup with System.Text.Json, DI registration, service interface/implementation pattern, full CRUD operations (GET, POST, PUT, DELETE), error handling, platform-specific clear-text traffic configuration, and async/await best practices. USE FOR: "REST API", "HttpClient", "call API", "GET request", "POST request", "API service", "JSON deserialization", "CRUD operations", "clear-text traffic", "consume API MAUI". DO NOT USE FOR: Aspire service discovery (use maui-aspire), authentication token handling (use maui-authentication), or local database storage (use maui-sqlite-database).
// ❌ Creates socket exhaustion — each instance opens a new connection
public async Task<List<Item>> GetItemsAsync()
{
using var client = new HttpClient();
var response = await client.GetAsync("https://api.example.com/items");
// ...
}
// ✅ Register once in DI, inject everywhere
builder.Services.AddSingleton(sp => new HttpClient
{
BaseAddress = new Uri("https://api.example.com")
});// ❌ Deadlocks on the UI thread var items = _apiService.GetItemsAsync().Result; // ✅ Always use async/await var items = await _apiService.GetItemsAsync();
// ❌ Tries to deserialize error HTML/JSON as your model var content = await response.Content.ReadAsStringAsync(); var items = JsonSerializer.Deserialize<List<Item>>(content, _jsonOptions); // ✅ Check status first response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); var items = JsonSerializer.Deserialize<List<Item>>(content, _jsonOptions) ?? [];
// ❌ Absolute URIs in every method — hard to change, easy to typo
await _httpClient.GetAsync("https://api.example.com/api/items");
// ✅ Set BaseAddress in DI, use relative URIs in methods
await _httpClient.GetAsync("api/items");// ❌ Crashes on network timeout, DNS failure, etc.
var items = await _apiService.GetItemsAsync();
// ✅ Catch both network and deserialization errors
try
{
var items = await _apiService.GetItemsAsync();
}
catch (HttpRequestException ex) { /* network or HTTP error */ }
catch (JsonException ex) { /* malformed response */ }Local dev servers on `http://` are blocked by default. Configure exceptions:
The Android emulator maps `10.0.2.2` to the host machine. `localhost` refers to the emulator itself.
// ❌ On Android emulator, this hits the emulator, not your dev machine
new Uri("http://localhost:5000")
// ✅ Use the emulator's host loopback address
new Uri("http://10.0.2.2:5000")iOS simulators use `localhost` directly.
APIs typically use camelCase; C# properties are PascalCase. Without `JsonSerializerOptions`, deserialization silently returns default values.
// ❌ Properties stay null/default — no error thrown
JsonSerializer.Deserialize<Item>(content);
// ✅ Configure casing policy
private static readonly JsonSerializerOptions _jsonOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true
};| Scenario | Error handling approach | |---|---| | Failure is unexpected (auth'd endpoints) | `EnsureSuccessStatusCode()` — throws `HttpRequestException` | | Need to branch on status codes | Check `IsSuccessStatusCode` or `response.StatusCode` | | Network may be unreliable (mobile) | Wrap in `try/catch` for `HttpRequestException` | | Response format may vary | Also catch `JsonException` |
A collection of 41 skills for .NET MAUI development, UI/UX design reasoning, and Xamarin migration, designed for use with GitHub Copilot CLI and Claude Code.
Guide for making .NET MAUI apps accessible — screen reader support via SemanticProperties, heading levels, AutomationProperties…
.NET MAUI view animations, custom animations, easing functions, rotation, scale, translation, and fade effects. USE FOR: "animate…
.NET MAUI app icon configuration, splash screen setup, SVG to PNG conversion at build time, composed/adaptive icons, and…
.NET MAUI app lifecycle guidance covering the four app states (not running, running, deactivated, stopped), cross-platform Window…
Guide for .NET MAUI apps consuming .NET Aspire-hosted backend services. Covers AppHost configuration, service discovery for…
Add authentication to .NET MAUI apps. Covers WebAuthenticator for generic OAuth 2.0 / social login, and MSAL.NET for Microsoft…