Building AI-Driven ASP.NET Core APIs: Hands-On Guide for .NET Developers
Executive Summary
AI-Driven Development in ASP.NET Core
– In modern enterprise applications, AI transforms static APIs into intelligent systems that analyze user feedback, generate personalized content, and automate decision-making. This guide builds a production-ready Feedback Analysis API that uses OpenAI’s GPT-4o-mini to categorize customer feedback, extract sentiment, and suggest actionable insights—solving real-world problems like manual review bottlenecks while ensuring scalability and security for enterprise deployments.
Prerequisites
- .NET 10 SDK (latest stable)
- Visual Studio 2022 or VS Code with C# Dev Kit
- OpenAI API key (get from platform.openai.com)
- NuGet packages:
OpenAI,Microsoft.Extensions.Http,Microsoft.EntityFrameworkCore.Sqlite
Run these commands to scaffold the project:
dotnet new webapi -o AiFeedbackApi --use-program-main
cd AiFeedbackApi
dotnet add package OpenAI --prerelease
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design
code .
Step-by-Step Implementation
Step 1: Configure AI Settings Securely
Add your OpenAI key to appsettings.json using User Secrets in development:
// appsettings.json
{
"AI": {
"OpenAI": {
"ApiKey": "your-api-key-here",
"Model": "gpt-4o-mini"
}
},
"ConnectionStrings": {
"Default": "Data Source=feedback.db"
}
}
Step 2: Create the Domain Model with Primary Constructors
Define our feedback entity using modern C# 13 primary constructors:
// Models/FeedbackItem.cs
public class FeedbackItem(int id, string text, string category, double sentimentScore)
{
public int Id { get; } = id;
public required string Text { get; init; } = text;
public string Category { get; set; } = category;
public double SentimentScore { get; set; } = sentimentScore;
public FeedbackItem() : this(0, string.Empty, string.Empty, 0) { }
}
Step 3: Build the AI Analysis Service
Create a robust, typed AI service using the official OpenAI client and HttpClientFactory fallback:
// Services/IAiFeedbackAnalyzer.cs
public interface IAiFeedbackAnalyzer
{
Task<(string Category, double SentimentScore)> AnalyzeAsync(string feedbackText);
}
// Services/AiFeedbackAnalyzer.cs
using OpenAI.Chat;
using OpenAI;
public class AiFeedbackAnalyzer(OpenAIClient client, IConfiguration config) : IAiFeedbackAnalyzer
{
private readonly ChatClient _chatClient = client.GetChatClient(config["AI:OpenAI:Model"] ?? "gpt-4o-mini");
public async Task<(string Category, double SentimentScore)> AnalyzeAsync(string feedbackText)
{
var messages = new List
{
new SystemChatMessage("""
Analyze customer feedback and respond ONLY with JSON:
{"category": "positive|negative|neutral|suggestion|bug", "sentiment": 0.0-1.0}
Categories: positive, negative, neutral, suggestion, bug.
Sentiment: 1.0 = very positive, 0.0 = very negative.
"""),
new UserChatMessage(feedbackText)
};
var response = await _chatClient.CompleteChatAsync(messages);
var jsonResponse = response.Value.Content[0].Text;
// Parse structured JSON response safely
using var doc = JsonDocument.Parse(jsonResponse);
var category = doc.RootElement.GetProperty("category").GetString() ?? "neutral";
var sentiment = doc.RootElement.GetProperty("sentiment").GetDouble();
return (category, sentiment);
}
}
Step 4: Set Up Dependency Injection and DbContext
Register services in Program.cs with minimal APIs:
// Program.cs
using Microsoft.EntityFrameworkCore;
using OpenAI;
var builder = WebApplication.CreateBuilder(args);
var apiKey = builder.Configuration["AI:OpenAI:ApiKey"]
?? throw new InvalidOperationException("OpenAI ApiKey is required");
builder.Services.AddOpenAIClient(apiKey);
builder.Services.AddScoped<IAiFeedbackAnalyzer, AiFeedbackAnalyzer>();
builder.Services.AddDbContext(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("Default")));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapFallback(() => Results.NotFound());
app.Run();
// AppDbContext.cs
public class AppDbContext(DbContextOptions options) : DbContext(options)
{
public DbSet<FeedbackItem> FeedbackItems { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<FeedbackItem>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Category).HasMaxLength(50);
});
}
}
Step 5: Implement Minimal API Endpoints
Add intelligent endpoints that process feedback in real-time:
// Add to Program.cs after app.Build()
app.MapPost("/api/feedback/analyze", async (IAiFeedbackAnalyzer analyzer, [FromBody] string text) =>
{
var (category, sentiment) = await analyzer.AnalyzeAsync(text);
return Results.Ok(new { Category = category, SentimentScore = sentiment });
});
app.MapPost("/api/feedback", async (AppDbContext db, IAiFeedbackAnalyzer analyzer, [FromBody] string text) =>
{
var (category, sentiment) = await analyzer.AnalyzeAsync(text);
var feedback = new FeedbackItem(0, text, category, sentiment);
db.FeedbackItems.Add(feedback);
await db.SaveChangesAsync();
return Results.Created($"/api/feedback/{feedback.Id}", feedback);
});
app.MapGet("/api/feedback/stats", async (AppDbContext db) =>
Results.Ok(await db.FeedbackItems
.GroupBy(f => f.Category)
.Select(g => new { Category = g.Key, Count = g.Count(), AvgSentiment = g.Average(f => f.SentimentScore) })
.ToListAsync()));
Step 6: Test Your AI API
Run dotnet run and test with Swagger or curl:
curl -X POST "https://localhost:5001/api/feedback/analyze" \
-H "Content-Type: application/json" \
-d '"The UI is intuitive and fast!"'
# Response: {"category":"positive","sentimentScore":0.92}
Production-Ready C# Examples
Here’s our complete, optimized controller alternative using primary constructors and source generators:
[ApiController]
[Route("api/v1/[controller]")]
public class FeedbackController(AppDbContext db, IAiFeedbackAnalyzer analyzer) : ControllerBase
{
[HttpPost]
public async Task<IActionResult> AnalyzeAndStore([FromBody] AnalyzeRequest request)
{
ArgumentNullException.ThrowIfNull(request.Text);
var (category, sentiment) = await analyzer.AnalyzeAsync(request.Text);
var item = new FeedbackItem(0, request.Text, category, sentiment);
db.FeedbackItems.Add(item);
await db.SaveChangesAsync();
return CreatedAtAction(nameof(GetById), new { id = item.Id }, item);
}
[HttpGet("{id:int}")]
public async Task<IActionResult> GetById(int id) =>
await db.FeedbackItems.FindAsync(id) is { } item
? Ok(item)
: NotFound();
}
public record AnalyzeRequest(string Text);
Common Pitfalls & Troubleshooting
- API Key Leaks: Never commit keys—use
dotnet user-secretsand Azure Key Vault in prod. - Rate Limits: Implement
Pollyretry policies:AddHttpClient().AddPolicyHandler(...). - JSON Parsing Failures: Always validate AI responses with
JsonDocumentand provide fallbacks. - Cold Starts: Pre-warm AI clients in
IHostedService. - Token Limits: Truncate long inputs:
text[..Math.Min(4000, text.Length)].
Performance & Scalability Considerations
- Caching: Cache frequent analysis patterns with
IMemoryCache(TTL: 5min). - Background Processing: Use
IBackgroundService+ Channels for batch analysis. - Distributed Tracing: Integrate OpenTelemetry for AI call monitoring.
- Model Routing: Abstract
IAiProviderto switch between OpenAI, Azure OpenAI, or local models. - Horizontal Scaling: Stateless services + Redis for shared cache/state.
Practical Best Practices
- Always implement structured prompting with system messages for consistent JSON output.
- Use record types for requests/responses to leverage source generators.
- Implement circuit breakers for AI dependencies using Polly.
- Add unit tests mocking
OpenAIClientwithMoq. - Log AI requests/responses (anonymized) with Serilog for model improvement.
- Enable streaming responses for long completions:
chatClient.CompleteChatStreamingAsync().
Conclusion
You’ve built a production-grade AI-powered Feedback API that scales from MVP to enterprise. Next steps: integrate with Blazor frontend, add RAG with vector databases, or deploy to Azure Container Apps with auto-scaling. Keep iterating—AI development is about continuous improvement.
FAQs
1. How do I handle OpenAI rate limits in production?
Implement exponential backoff with Polly:
services.AddHttpClient<IAiFeedbackAnalyzer>().AddPolicyHandler(
Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
.WaitAndRetryAsync(3, retry => TimeSpan.FromSeconds(Math.Pow(2, retry))));
2. Can I use local ML.NET models instead of OpenAI?
Yes! Create IAiFeedbackAnalyzer implementations for both and use DI feature flags to switch.
3. How do I secure the AI endpoints?
Add [Authorize] with JWT, rate limiting via AspNetCoreRateLimit, and validate inputs with FluentValidation.
4. What’s the cost of GPT-4o-mini for 1M feedbacks?
~400 input tokens per analysis × $0.15/1M tokens = ~$0.10 per 1K analyses. Cache aggressively.
5. How do I add streaming AI responses?
Use CompleteChatStreamingAsync() and Response.StartAsync() for real-time UI updates.
6. Can I deploy this to Azure?
Perfect for Azure Container Apps + Azure OpenAI (same SDK). Use Managed Identity for keys.
7. How do I test AI responses deterministically?
Mock OpenAIClient or use fixed prompt responses in integration tests.
8. What’s the latency impact of AI calls?
200-800ms per call. Use async/await everywhere and consider client-side caching.
You might also like these
AI-Native .NET: Building Intelligent Applications with Azure OpenAI, Semantic Kernel, and ML.NET
AI-Augmented .NET Backends: Building Intelligent, Agentic APIs with ASP.NET Core and Azure OpenAI
Master Effortless Cloud-Native .NET Microservices Using DAPR, gRPC & Azure Kubernetes Service
Build an AI chat app with .NET (Microsoft Learn) — Quickstart showing how to use OpenAI or Azure OpenAI models with .NET.
🔗 https://learn.microsoft.com/en-us/dotnet/ai/quickstarts/build-chat-app
Develop .NET apps with AI features (Microsoft Learn) — Overview of AI integration in .NET apps (APIs, services, tooling).
🔗 https://learn.microsoft.com/en-us/dotnet/ai/overview
AI-Powered Group Chat sample with SignalR + OpenAI (Microsoft Learn) — Demonstrates real-time chat with AI in an ASP.NET Core app.
🔗 https://learn.microsoft.com/en-us/aspnet/core/tutorials/ai-powered-group-chat/ai-powered-group-chat?view=aspnetcore-9.0
