A reference .NET application implementing an e-commerce website using a services-based architecture with Aspire.
An educational AI customer-support service integrated into dotnet/eShop:
- RAG over eight demo-policy documents stored in PostgreSQL with pgvector.
- A custom C# agent loop and a Microsoft Agent Framework workflow graph.
- Tools for knowledge search, order status and support-ticket creation, with permission and order-ownership checks enforced in C#.
- Persistent conversations and replay of saved requests by identifier.
- Execution traces, per-message timing and token metrics, and 23 offline checks automated in GitHub Actions.
Start with Support.API, the support page and the offline checks. The initial support implementation shows the original changes added to eShop.
Read the support architecture and the decisions on tool authority, agent and workflow orchestration, and model integration.
Engineering comments, diagnostics, test output and documentation use English. See the language conventions; the support page also uses English labels and controls. Stored conversation content retains its original language.
Complete the prerequisites, including cloning this repository. Run the following commands from the repository root on the development machine that hosts the AppHost. The configuration block uses Bash and prompts for the API key without adding its literal value to the command history:
bash <<'BASH'
set -e
read -r -s -p "OpenAI API key: " eshop_support_key </dev/tty
printf '\n'
dotnet user-secrets set "Parameters:support-openai-key" "$eshop_support_key" --project src/eShop.AppHost
unset eshop_support_key
dotnet user-secrets set "Support:Model" "gpt-5.4-mini" --project src/eShop.AppHost
BASHThe AppHost stores development configuration using .NET user secrets and passes the API key to Support.API through a secret Aspire parameter. User secrets are stored outside the repository; they are not encrypted and are intended for development. See the .NET user-secrets documentation.
Support.API calls the OpenAI Responses API directly. Its default chat model is
gpt-5.4-mini; embeddings use text-embedding-3-small with 1536 dimensions.
The upstream Foundry chatbot is a separate feature.
With the container runtime running, start the application:
ESHOP_USE_HTTP_ENDPOINTS=1 aspire runThe first startup imports the demo documents and generates their embeddings. Unchanged documents reuse the stored embeddings on subsequent starts.
Open http://localhost:5045/support and sign in through eShop. The support page uses English labels and controls. The current assistant prompts and knowledge documents still use Russian; saved conversation content retains its original language. Try a general question without selecting an order or enabling ticket creation:
Можно вернуть кофемолку, если я открыл коробку, но не пользовался?
Then ask a follow-up in the same conversation:
А когда вернут деньги?
For the order demo, create an order through the storefront, select it on the support page and ask to check its status. Enable ticket creation when you want to save a demo support ticket. Inspect the sources, execution trace and metrics shown with the reply. Use "Repeat last request" to replay the saved reply.
For development on a remote server, forward the browser-facing ports
5045 (WebApp), 5223 (Identity.API) and 18848 (Aspire dashboard) through SSH
or your IDE. Open the application through localhost on your own computer.
The current HTTP and callback settings are for local or tunneled development.
- For a valid order owned by the signed-in buyer, enabling
AllowTicketcurrently requests ticket creation in both modes. The agent completes this action in C# if the model omits it. Model-based ticket-necessity decisions are planned. - Tickets are stored in
support_ticketsin theknowledgedatabase and do not contact an external support service. Store policies are fictional demo rules. - Repeating a saved request with the same
conversationId,requestIdand payload returns its saved reply. Reusing that identifier with different parameters returns HTTP 409. Matching question text alone is not a replay. - Reply validation checks retrieved source IDs and known ticket numbers. Invalid drafts get one repair attempt before a deterministic fallback.
- The 23 offline checks use fake dependencies. They verify selected code paths; real-model quality and PostgreSQL integration require separate evaluation.
Run the support checks without an API key or a running application:
dotnet run --project tests/Support.SelfTests/Support.SelfTests.csproj --configuration ReleaseExpected final output:
OK: 23 offline checks passed. No external APIs or PostgreSQL were called.
This version of eShop is based on .NET 10.
Previous eShop versions:
-
Install a .NET 10 SDK that satisfies
global.json. -
Install the Aspire CLI and verify that it is available:
aspire --version -
Install and start an OCI-compatible container runtime. Docker Desktop is the recommended default. Podman is also supported; follow the Aspire prerequisites to configure it.
-
Clone the repository:
git clone https://github.com/dotnet/eShop.git cd eShop
No separate Aspire workload or Visual Studio component is required; the AppHost SDK and hosting integrations are referenced by the projects in this repository.
- Visual Studio with the
ASP.NET and web developmentworkload. - Visual Studio Code with C# Dev Kit and the Aspire extension.
- The .NET MAUI workload if you want to run the client apps.
Warning
Ensure that your container runtime is running before starting eShop.
From the repository root, run:
aspire runThe root aspire.config.json selects src/eShop.AppHost/eShop.AppHost.csproj, avoiding ambiguity with the test AppHosts in the repository. When startup completes, the CLI prints a dashboard URL similar to:
Dashboard: https://localhost:<port>/login?t=<token>
Press Ctrl+C to stop the AppHost. See the aspire run command for additional options.
To run the AppHost in the background instead:
aspire start
aspire psWhen you are finished, run aspire stop. See the aspire start command for details.
- Open
eShop.Web.slnf. - Set
src/eShop.AppHost/eShop.AppHost.csprojas the startup project. - Press Ctrl+F5 to start eShop and open the Aspire dashboard.
Run the server tests:
dotnet test --solution eShop.Web.slnfRun the Playwright browser journeys. Playwright starts the AppHost automatically, so ensure your container runtime is running first.
npm ci
npx playwright install chromium
npm run test:e2eThis option provisions a Microsoft Foundry resource during local development, so first authenticate to Azure and configure the subscription and location:
az login
aspire secret set "Azure:SubscriptionId" "<subscription-id>"
aspire secret set "Azure:Location" "eastus"Then enable Foundry and start eShop:
$env:UseFoundry = "true"
aspire runAspire provisions the gpt-4.1-mini and text-embedding-3-small deployments and injects their connection information into the consuming projects. The Foundry hosting integration currently uses a preview package. See local Azure provisioning and the Microsoft Foundry hosting integration for details.
The AppHost is already configured with an Azure Container Apps environment, so the Aspire CLI can deploy directly from the application model. See the Aspire Azure Container Apps deployment guide for details.
Warning
This sample deploys PostgreSQL, Redis, and RabbitMQ as containers in Azure Container Apps. This configuration is intended for evaluation and demonstrations, not production data.
Prerequisites:
- The prerequisites listed above, including a running container runtime.
- The Azure CLI, an active Azure subscription, and permission to create resources.
Sign in, optionally preview the deployment pipeline, and deploy:
az login
aspire deploy --list-steps
aspire deployFor local interactive use, aspire deploy prompts for missing Azure settings. For non-interactive use, provide them explicitly:
$env:Azure__SubscriptionId = "<subscription-id>"
$env:Azure__Location = "eastus"
$env:Azure__ResourceGroup = "rg-eshop-demo"
aspire deploy --non-interactiveUse aspire publish when you need deployment artifacts for inspection or another deployment tool. Running it first is not required: aspire deploy invokes the deployment pipeline and its dependencies directly rather than consuming an earlier publish output.
When you no longer need the deployment, run aspire destroy. This deletes the entire configured resource group, including resources that Aspire did not create, so review the target carefully before confirming.
For more information on contributing to this repo, read the contribution documentation and the Code of Conduct.
The sample catalog data is defined in catalog.json. Those product names, descriptions, and brand names are fictional and were generated using GPT-35-Turbo, and the corresponding product images were generated using DALL·E 3.
For a version of this app configured for deployment on Azure, please view the eShop on Azure repo.

