Why Use OpenAI with .NET 9?

.NET 9 brings Native AOT, built-in OpenAPI, and minimal APIs that fit AI-first apps perfectly. Combined with OpenAI’s API, you can add:

This article shows you how to build production-ready integrations.

Getting Started with OpenAI in .NET 9

1. Install Packages

You can use the official OpenAI .NET SDK or raw HttpClient.

dotnet add package OpenAI

If you prefer HttpClient (no SDK dependency):

dotnet add package Microsoft.Extensions.Http

2. Add API Key to Configuration

appsettings.json:

{
  "OpenAI": {
    "ApiKey": "YOUR_API_KEY_HERE"
  }
}

Or environment variable:

setx OPENAI_API_KEY "sk-xxxx"

3. Register OpenAI Client in Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpClient("OpenAI", client =>
{
    client.BaseAddress = new Uri("https://api.openai.com/v1/");
    client.DefaultRequestHeaders.Add("Authorization", $"Bearer {builder.Configuration["OpenAI:ApiKey"]}");
});

var app = builder.Build();

Example 1: ChatGPT in Minimal API

app.MapPost("/chat", async (HttpClientFactory httpFactory, ChatRequest request) =>
{
    var client = httpFactory.CreateClient("OpenAI");

    var payload = new
    {
        model = "gpt-4o-mini",
        messages = new[]
        {
            new { role = "system", content = "You are a helpful assistant." },
            new { role = "user", content = request.Message }
        }
    };

    var response = await client.PostAsJsonAsync("chat/completions", payload);
    var result = await response.Content.ReadFromJsonAsync<ChatResponse>();

    return Results.Ok(result?.Choices.FirstOrDefault()?.Message?.Content);
});

record ChatRequest(string Message);
record ChatResponse(List<Choice> Choices);
record Choice(Message Message);
record Message(string Role, string Content);

Test with:

curl -X POST https://localhost:5001/chat -H "Content-Type: application/json" -d "{ \"message\": \"Tell me about .NET 9\" }"

Example 2: Embeddings for Search

app.MapPost("/embed", async (HttpClientFactory httpFactory, TextRequest req) =>
{
    var client = httpFactory.CreateClient("OpenAI");

    var payload = new
    {
        model = "text-embedding-3-small",
        input = req.Text
    };

    var response = await client.PostAsJsonAsync("embeddings", payload);
    var result = await response.Content.ReadFromJsonAsync<EmbedResponse>();

    return Results.Ok(result?.Data.FirstOrDefault()?.Embedding);
});

record TextRequest(string Text);
record EmbedResponse(List<EmbedData> Data);
record EmbedData(List<float> Embedding);

Use cases: semantic search, clustering, recommendations.

Example 3: Image Generation (DALL·E)

app.MapPost("/image", async (HttpClientFactory httpFactory, TextRequest req) =>
{
    var client = httpFactory.CreateClient("OpenAI");

    var payload = new
    {
        prompt = req.Text,
        model = "gpt-image-1",
        size = "512x512"
    };

    var response = await client.PostAsJsonAsync("images/generations", payload);
    var result = await response.Content.ReadFromJsonAsync<ImageResponse>();

    return Results.Ok(result?.Data.FirstOrDefault()?.Url);
});

record ImageResponse(List<ImageData> Data);
record ImageData(string Url);

Example 4: Streaming Responses (Chatbot UX)

app.MapGet("/stream", async (HttpContext context, HttpClientFactory httpFactory) =>
{
    var client = httpFactory.CreateClient("OpenAI");

    var payload = new
    {
        model = "gpt-4o-mini",
        messages = new[]
        {
            new { role = "user", content = "Explain .NET 9 in 3 bullet points" }
        },
        stream = true
    };

    context.Response.ContentType = "text/event-stream";
    using var req = new HttpRequestMessage(HttpMethod.Post, "chat/completions")
    {
        Content = JsonContent.Create(payload)
    };
    using var resp = await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);

    using var reader = new StreamReader(await resp.Content.ReadAsStreamAsync());
    while (!reader.EndOfStream)
    {
        var line = await reader.ReadLineAsync();
        if (!string.IsNullOrWhiteSpace(line) && line.StartsWith("data:"))
        {
            await context.Response.WriteAsync(line + "\n");
            await context.Response.Body.FlushAsync();
        }
    }
});

This enables real-time token streaming for chatbots or IDE assistants.

Best Practices

GEO Optimization Notes

Summary

With .NET 9 + OpenAI, you can build chatbots, search engines, image generators, and real-time streaming AI apps with minimal code. Key takeaways: