davidfowl/AspNetCoreDiagnosticScenarios
This repository has examples of broken patterns in ASP.NET Core applications
Stale and unlicensed — last commit 2y ago
worst of 4 axesno license — legally unclear; last commit was 2y ago…
no license — can't legally use code; no tests detected…
Documented and popular — useful reference codebase to read through.
no license — can't legally use code; last commit was 2y ago…
- ✓42+ active contributors
- ⚠Stale — last commit 2y ago
- ⚠Concentrated ownership — top contributor handles 54% of recent commits
Show 3 more →Show less
- ⚠No license — legally unclear to depend on
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: publish a permissive license (MIT, Apache-2.0, etc.)
- →Fork & modify Concerns → Mixed if: add a LICENSE file
- →Deploy as-is Concerns → Mixed if: add a LICENSE file
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/davidfowl/aspnetcorediagnosticscenarios)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/davidfowl/aspnetcorediagnosticscenarios on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: davidfowl/AspNetCoreDiagnosticScenarios
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/davidfowl/AspNetCoreDiagnosticScenarios shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
AVOID — Stale and unlicensed — last commit 2y ago
- 42+ active contributors
- ⚠ Stale — last commit 2y ago
- ⚠ Concentrated ownership — top contributor handles 54% of recent commits
- ⚠ No license — legally unclear to depend on
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live davidfowl/AspNetCoreDiagnosticScenarios
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/davidfowl/AspNetCoreDiagnosticScenarios.
What it runs against: a local clone of davidfowl/AspNetCoreDiagnosticScenarios — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in davidfowl/AspNetCoreDiagnosticScenarios | Confirms the artifact applies here, not a fork |
| 2 | Default branch master exists | Catches branch renames |
| 3 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 4 | Last commit ≤ 741 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of davidfowl/AspNetCoreDiagnosticScenarios. If you don't
# have one yet, run these first:
#
# git clone https://github.com/davidfowl/AspNetCoreDiagnosticScenarios.git
# cd AspNetCoreDiagnosticScenarios
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of davidfowl/AspNetCoreDiagnosticScenarios and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "davidfowl/AspNetCoreDiagnosticScenarios(\\.git)?\\b" \\
&& ok "origin remote is davidfowl/AspNetCoreDiagnosticScenarios" \\
|| miss "origin remote is not davidfowl/AspNetCoreDiagnosticScenarios (artifact may be from a fork)"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "Scenarios/Program.cs" \\
&& ok "Scenarios/Program.cs" \\
|| miss "missing critical file: Scenarios/Program.cs"
test -f "Scenarios/Startup.cs" \\
&& ok "Scenarios/Startup.cs" \\
|| miss "missing critical file: Scenarios/Startup.cs"
test -f "AspNetCoreGuidance.md" \\
&& ok "AspNetCoreGuidance.md" \\
|| miss "missing critical file: AspNetCoreGuidance.md"
test -f "AsyncGuidance.md" \\
&& ok "AsyncGuidance.md" \\
|| miss "missing critical file: AsyncGuidance.md"
test -f "Scenarios/Controllers/AsyncVoidController.cs" \\
&& ok "Scenarios/Controllers/AsyncVoidController.cs" \\
|| miss "missing critical file: Scenarios/Controllers/AsyncVoidController.cs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 741 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~711d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/davidfowl/AspNetCoreDiagnosticScenarios"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
A curated collection of broken ASP.NET Core patterns paired with fixes and guidance documents. The repo houses 15+ runnable diagnostic scenarios (AsyncVoidController, MemoryLeakController, HttpClientController, etc.) that demonstrate real performance and concurrency bugs found in production applications, with detailed walkthroughs on proper solutions. Monolithic structure: Scenarios/ folder contains Controllers/ (15 broken scenario endpoints), Services/ (supporting classes like PokemonService, RemoteConnection), Infrastructure/ (TaskExtensions), and Model/ (data classes). Top-level guidance markdown files (AsyncGuidance.md, Gotchas.md) provide the reference material; pokemon.json seed data and index.html provide test UI.
👥Who it's for
ASP.NET Core developers and architects who need to understand and avoid common pitfalls when building scalable web services—especially those dealing with async/await misconceptions, thread pool starvation, HttpClient misuse, and memory leaks in production systems.
🌱Maturity & risk
Actively maintained reference material with established guidance documents (AsyncGuidance.md, HttpClientGuidance.md, AspNetCoreGuidance.md) and educational focus rather than rapid feature development. No visible CI/CD badges in snippet, but the repo serves as authoritative documentation backed by real customer issues—treated as production-grade learning material rather than a library.
Single-maintainer repo (davidfowl) with educational rather than production-code focus; low risk for application dependencies since this is not a library. Primary risk is guidance becoming stale relative to .NET runtime behavior changes; verify examples against your target .NET version (likely .NET 6+ based on ASP.NET Core positioning).
Active areas of work
The repository appears to be mature reference material—commit activity likely sporadic as it documents known patterns rather than chasing new features. Watch for updates aligning with .NET runtime releases or new async/HttpClient best practices from Microsoft.
🚀Get running
Check README for instructions.
Daily commands:
cd Scenarios
dotnet run
# App will start on http://localhost:5000 (or port shown in console)
# Navigate to /index.html to see UI with links to each scenario endpoint
🗺️Map of the codebase
Scenarios/Program.cs— Application entry point and ASP.NET Core bootstrap; essential for understanding how the diagnostic scenarios are configured and hosted.Scenarios/Startup.cs— Dependency injection and middleware configuration; defines how services and controllers are wired together across all scenarios.AspNetCoreGuidance.md— Primary guidance document on scalable ASP.NET Core patterns; required reading for understanding the repo's teaching objectives.AsyncGuidance.md— Core asynchronous programming patterns and pitfalls; directly addresses the most common diagnostic issues demonstrated in controllers.Scenarios/Controllers/AsyncVoidController.cs— Canonical anti-pattern example showing async void misuse; demonstrates a critical diagnostic scenario that impacts reliability.Scenarios/Services/PokemonService.cs— Primary business logic service; shows integration patterns, HTTP client usage, and async/await best practices across the codebase.HttpClientGuidance.md— HttpClient configuration and reuse patterns; addresses pooling, lifetime management, and common performance pitfalls.
🛠️How to make changes
Add a new diagnostic scenario controller
- Create a new controller class in Scenarios/Controllers/ that inherits from ControllerBase, naming it after the anti-pattern (e.g., DeadlockController.cs) (
Scenarios/Controllers/) - Define one or more HTTP endpoints (e.g., [HttpGet("bad")] and [HttpGet("good")]) demonstrating broken vs. correct patterns (
Scenarios/Controllers/{NewController}.cs) - Inject required services (PokemonService, ILogger, etc.) via constructor dependency injection registered in Startup.cs (
Scenarios/Startup.cs) - Add route and documentation in wwwroot/index.html to allow users to trigger and test the scenario (
Scenarios/wwwroot/index.html) - Create a corresponding guidance section in Guidance.md or AsyncGuidance.md explaining the anti-pattern and how to fix it (
AsyncGuidance.md)
Add a new service or business logic component
- Create a new service interface and implementation in Scenarios/Services/ (e.g., ICustomService.cs and CustomService.cs) (
Scenarios/Services/) - Implement async Task-returning methods following the patterns shown in PokemonService.cs, using cancellation tokens where applicable (
Scenarios/Services/{NewService}.cs) - Register the service in Startup.cs using services.AddScoped<ICustomService, CustomService>() or appropriate lifetime (
Scenarios/Startup.cs) - Inject and use the service in one or more controllers, demonstrating proper async/await and cancellation handling (
Scenarios/Controllers/{Controller}.cs)
Add a database model and Entity Framework integration
- Define a new entity class in Scenarios/Model/ with properties matching your domain (e.g., CustomData.cs) (
Scenarios/Model/) - Add a DbSet<CustomData> property to PokemonDbContext in Scenarios/PokemonDbContext.cs and configure it in OnModelCreating if needed (
Scenarios/PokemonDbContext.cs) - Create a service that queries the DbContext asynchronously, following patterns in PokemonService.cs (
Scenarios/Services/{NewService}.cs) - Expose the service via controller endpoints that demonstrate proper async query handling and disposal (
Scenarios/Controllers/{NewController}.cs)
🔧Why these technologies
- ASP.NET Core 3.1+ — Primary framework for building scalable HTTP services; enables demonstration of async/await patterns, middleware, and dependency injection at scale.
- Entity Framework Core — ORM for data access scenarios; provides context for demonstrating async query patterns, connection pooling, and common database-related anti-patterns.
- HttpClient (with PoolingHttpClientFactory) — Standard .NET HTTP client abstraction; critical for teaching proper socket exhaustion, connection pooling, and handler reuse patterns.
- CancellationToken — Built-in async cancellation mechanism; essential for demonstrating graceful shutdown, request timeout handling, and resource cleanup.
- Markdown documentation files — Lightweight, version-controllable guides integrated with code examples; allows teaching anti-patterns alongside corrected implementations.
⚖️Trade-offs already made
-
Controllers demonstrate anti-patterns directly rather than behind conditional flags
- Why: Makes the broken code immediately visible and executable, supporting hands-on learning through diagnostic tools (profilers, debuggers).
- Consequence: Production-like code; developers must be cautious not to copy anti-pattern implementations into real applications without understanding the fixes.
-
Single in-memory and SQLite-backed database (PokemonDbContext) across all scenarios
- Why: Simplifies setup, allows self-contained diagnostics without external infrastructure, and keeps focus on ASP.NET Core patterns rather than database administration.
- Consequence: Does not expose distributed transaction, replication, or high-concurrency database issues; scenarios remain CPU and memory-focused.
-
Use public pokeapi.co as external HTTP dependency rather than a mock
- Why: Demonstrates real network latency, timeout handling, and actual HttpClient pooling behavior in live HTTP calls.
- Consequence: Tests depend on external service availability; adds ~200–500ms latency to scenarios and requires internet connectivity.
-
Minimal UI (static index.html) instead of rich frontend framework
- Why: Keeps focus on server-side diagnostics; avoids JavaScript complexity that would obscure ASP.NET Core teaching objectives.
- Consequence: UI lacks dynamic filtering and real-time metrics; developers use browser dev tools and profilers directly.
🚫Non-goals (don't propose these)
- Does not provide production-ready error handling or resilience patterns (Polly, circuit breakers are not used).
- Does not implement authentication, authorization, or security patterns.
- Does not cover distributed tracing, structured logging infrastructure, or observability tooling configuration.
- Does not address containerization, Kubernetes, or cloud-specific deployment concerns
🪤Traps & gotchas
No explicit test data setup: pokemon.json is checked in but ensure PokemonDbContext migrations match your EF version or seed may fail. Port conflicts: Default ASP.NET Core ports (5000/5001) must be available. Diagnostics require monitoring: Some scenarios (HighCpuController, MemoryLeakController) only manifest issues under load—use dotnet-counters or PerfView to observe. Async execution context: Some scenarios depend on proper SynchronizationContext behavior; running in non-web contexts (unit tests without test framework setup) may mask issues.
🏗️Architecture
💡Concepts to learn
- Async void anti-pattern — Core teaching of this repo—async void enables fire-and-forget calls that crash the app silently; essential to understand why only event handlers should use it
- ThreadPool starvation via Task.Run in async code — Scenarios like AsyncFactoryController demonstrate how Task.Run in request handlers exhausts the thread pool, blocking subsequent requests
- HttpClient socket exhaustion — HttpClientController shows the real-world impact of not reusing HttpClient instances—DNS caching and port exhaustion that crashes production
- ConfigureAwait(false) for library code — Prevents SynchronizationContext-induced deadlocks in ASP.NET Core; AsyncGuidance.md explains when and why this is critical
- CancellationToken propagation — CancelAsyncOperationController and CancelLegacyOperationController demonstrate why token threading prevents resource waste and enables graceful shutdown
- Ephemeral object memory pressure — EphemeralOperationController + MemoryLeakController show how unreleased allocations in hot paths cause Gen2 promotions and GC pressure
- Fire-and-forget operation patterns — FireAndForgetController demonstrates the pitfall of not awaiting background work and the correct patterns (BackgroundTaskQueue, hosted services) in ASP.NET Core
🔗Related repos
dotnet/runtime— Official .NET runtime repo where async/ThreadPool behavior is implemented; reference when guidance contradicts observed behaviordotnet/aspnetcore— ASP.NET Core framework source; essential for understanding how Startup.cs and Controllers integrate with middlewaredavidfowl/AspNetCoreRxJS— Companion repo from same author showing reactive patterns as alternative to async/await for certain scenariosmicrosoft/dotnet-samples— Official Microsoft samples including async patterns and best practices that complement these diagnostic scenariosBenchmarkDotNet/BenchmarkDotNet— Performance measurement library used to validate fixes for the scenarios described (e.g., HttpClient reuse perf gains)
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for diagnostic scenarios controllers
The repo contains 10+ controller examples (AsyncVoidController.cs, MemoryLeakController.cs, HttpClientController.cs, etc.) demonstrating broken patterns, but there are no corresponding test files. Adding integration tests would validate that each scenario correctly exhibits its documented anti-pattern and that fixes work as intended. This is high-value because contributors can verify their understanding and improvements.
- [ ] Create Scenarios.Tests/Controllers/ directory with xUnit test project
- [ ] Add integration tests for AsyncVoidController.cs, FireAndForgetController.cs, and MemoryLeakController.cs demonstrating the broken behavior
- [ ] Add corresponding 'fixed' versions of these scenarios with passing tests showing the corrected pattern
- [ ] Reference specific guidance from AsyncGuidance.md and Guidance.md in test comments
Add practical examples and tests for HttpClientGuidance.md scenarios
HttpClientGuidance.md exists but HttpClientController.cs lacks comprehensive examples. The guidance document should have concrete, runnable code samples with corresponding tests. This fills a gap between theoretical guidance and practical implementation.
- [ ] Expand HttpClientController.cs with examples: static HttpClient reuse, proper socket exhaustion prevention, timeout configuration
- [ ] Create Scenarios.Tests/Services/HttpClientControllerTests.cs with integration tests for each pattern
- [ ] Add code snippets to HttpClientGuidance.md that directly reference the controller methods being tested
- [ ] Include performance/stress test examples showing socket exhaustion with broken vs. correct patterns
Create a continuous diagnostic output analyzer (runner with metrics)
The scenarios folder contains example controllers but no automated way to run them and validate they exhibit the expected diagnostic signatures (memory leaks, high CPU, thread starvation, etc.). Adding a diagnostic test harness would help contributors understand the real-world impact of each anti-pattern.
- [ ] Create Scenarios/DiagnosticsRunner/ScenarioRunner.cs to invoke each controller endpoint and capture metrics (memory, CPU, thread count, GC collections)
- [ ] Add configuration in Scenarios/Program.cs to expose a /diagnostics endpoint that runs scenarios and reports metrics
- [ ] Document expected diagnostic signatures in each controller with comments (e.g., 'Memory grows unbounded' for MemoryLeakController)
- [ ] Reference the metrics output in Guidance.md and AsyncGuidance.md so readers can see real evidence of the problems
🌿Good first issues
- Add a ConcurrencyController.cs scenario demonstrating race conditions in shared state (no locking)—requires minimal code but teaches critical lesson on thread-safety in async handlers.
- Expand Gotchas.md with a section on 'Async Lambda in LINQ Where()'—the repo hints at this but lacks a dedicated controller + walkthrough showing deferred execution traps.
- Create unit tests for TaskExtensions.cs (Scenarios/Infrastructure/TaskExtensions.cs currently has no test coverage)—add xUnit tests validating cancellation and timeout behaviors.
⭐Top contributors
Click to expand
Top contributors
- @davidfowl — 54 commits
- @sungam3r — 5 commits
- @talha-sayed — 2 commits
- @Meir017 — 1 commits
- @hairyputtar — 1 commits
📝Recent commits
Click to expand
Recent commits
bcc7ca3— add system.text.json good example to BigJsonInputController.cs (#119) (Meir017)3c059e8— Editorial changes (#117) (sungam3r)93ff293— Fix method name (#116) (sungam3r)1ba4f11— Fix typo (#115) (sungam3r)bbf00bf— Fix copy-pasted description (#114) (sungam3r)162f9ea— Clarify sentence (#113) (sungam3r)0a06ac7— fix typos (#110) (hairyputtar)c24493b— Update README.md (#109) (Kalyanimhala)9d5c8ee— Update AsyncGuidance.md (davidfowl)91b36e7— fix some typo and grammar issues (#105) (FarukhS52)
🔒Security observations
This repository is a diagnostic/educational project demonstrating anti-patterns and broken scenarios in ASP.NET Core. As such, security vulnerabilities are intentional. The main security concerns identified are: (1) fire-and-forget operations without proper error handling, (2) potential memory le
- Medium · Potential Insecure Deserialization Pattern —
Scenarios/Controllers/BigJsonInputController.cs, Scenarios/Controllers/BigJsonOutputController.cs. The repository contains BigJsonInputController and BigJsonOutput controller files suggesting large JSON payload handling. Without examining the actual implementation, JSON deserialization in ASP.NET Core could be vulnerable to DoS attacks or unsafe object deserialization if not properly configured with size limits and safe settings. Fix: Implement JSON size limits in Startup.cs, configure MaxRequestBodySize appropriately, and ensure JsonSerializerOptions are set to safe defaults. Use [FromBody] attributes with explicit model binding. - Medium · Fire-and-Forget Operations Without Proper Error Handling —
Scenarios/Controllers/FireAndForgetController.cs, Scenarios/Services/EphemeralOperation.cs. The presence of FireAndForgetController suggests asynchronous operations that may not properly track completion or handle exceptions. Fire-and-forget patterns without proper exception logging and tracking can hide critical errors and make debugging difficult. Fix: Implement proper async/await patterns, use hosted services for background operations, or use libraries like Hangfire for reliable background job execution. Always log exceptions from background operations. - Medium · Potential Memory Leak in Long-Running Services —
Scenarios/Controllers/MemoryLeakController.cs, Scenarios/Services/RemoteConnection.cs. The MemoryLeakController and RemoteConnection service files suggest scenarios involving resource management and long-lived connections. If connections or event handlers are not properly disposed, memory leaks can occur. Fix: Implement IDisposable/IAsyncDisposable patterns correctly, use 'using' statements, ensure all event handlers are unsubscribed, and implement proper connection pooling where applicable. - Medium · Async Void Method Anti-Pattern —
Scenarios/Controllers/AsyncVoidController.cs. The presence of AsyncVoidController indicates usage of async void methods, which is a known anti-pattern. Async void methods cannot be awaited and make exception handling difficult, potentially causing unhandled exceptions. Fix: Replace all async void methods with async Task methods. Async void should only be used for event handlers. - Low · Missing Dependency Information —
Scenarios/Scenarios.csproj. The dependency/package file content is not provided in the analysis. Unknown or outdated NuGet dependencies could contain known vulnerabilities. Fix: Provide the .csproj file content and perform NuGet audit using 'dotnet list package --vulnerable' or OWASP Dependency-Check to identify vulnerable dependencies. - Low · Potential Hardcoded Database Context Configuration —
Scenarios/PokemonDbContext.cs, Scenarios/Startup.cs. The presence of PokemonDbContext suggests database operations. Connection strings should not be hardcoded in source code. Fix: Store database connection strings in secure configuration providers (Azure Key Vault, appsettings.json with proper environment handling, environment variables). Use Secrets Manager for development. - Low · Static Analysis - Insufficient HTTP Security Headers —
Scenarios/Startup.cs, Scenarios/Program.cs. No evidence of security header configuration visible in the file structure. Missing headers like Content-Security-Policy, X-Frame-Options, X-Content-Type-Options could expose the application to various attacks. Fix: Add middleware to set security headers: X-Content-Type-Options, X-Frame-Options, Content-Security-Policy, Strict-Transport-Security, X-XSS-Protection. - Low · Potential Input Validation Gaps in Controllers —
Scenarios/Controllers/. Multiple controllers handling user input without explicit evidence of input validation. This could lead to injection attacks or unexpected behavior. Fix: Implement model validation using Data Annotations or FluentValidation. Always validate and sanitize user inputs. Use parameterized queries for database operations.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.