Skip to main content

Azure OpenAI C# Tutorial: Integrate GPT-4o in .NET

Learn how to integrate Azure OpenAI GPT-4o into your C# .NET application with this step-by-step tutorial. Code examples, best practices & tips. Start now!

If you want to build smart, AI-powered features into your applications, learning Azure OpenAI C# integration is one of the highest-return skills you can pick up in 2026. With the official Azure OpenAI SDK for .NET, you can call GPT-4o — OpenAI's flagship multimodal model — directly from your C# code in just a few lines. In this tutorial, you'll learn how to integrate GPT-4o into your .NET application, configure authentication securely, stream responses, and apply production-ready best practices.

Whether you're a beginner searching "how to use Azure OpenAI in C#", an intermediate developer looking for best practices, or a senior engineer designing a scalable AI service, this guide covers everything end to end with runnable code examples.

Why Use Azure OpenAI with C# Instead of the Public OpenAI API?

Both services give you access to GPT-4o, but Azure OpenAI offers advantages that matter for enterprise and production .NET workloads:

  • Enterprise security and compliance — Your data stays within your Azure tenant and is not used to train models. This is critical for industries with GDPR, HIPAA, or SOC 2 requirements.
  • Microsoft Entra ID (Azure AD) authentication — Use managed identities instead of hard-coded API keys, eliminating a whole class of secret-leak vulnerabilities.
  • Regional deployment — Pin your model to a specific region (East US, UK South, Australia East, Canada Central) for data residency.
  • SLA-backed availability and predictable provisioned throughput for high-traffic apps.
  • Native .NET tooling — First-class SDK support, dependency injection, and integration with the broader Azure ecosystem.

In short: if you're already building on .NET and Azure, the Azure OpenAI C# path is the natural, secure, and scalable choice.

Prerequisites Before You Integrate GPT-4o into .NET

Before writing any code, make sure you have the following ready:

  • An Azure subscription with access to Azure OpenAI Service (request access if your tenant doesn't have it yet).
  • An Azure OpenAI resource created in the Azure portal.
  • A GPT-4o model deployment — note the deployment name you give it; this is what you reference in code, not the model name.
  • .NET 8 or .NET 9 SDK installed.
  • Your resource endpoint URL (e.g. https://your-resource.openai.azure.com/).

Step 1: Install the Azure OpenAI SDK for .NET

The modern, recommended package is Azure.AI.OpenAI, which builds on top of the official OpenAI library and adds Azure-specific authentication. Add it to your project:

// Run in your project directory
// dotnet add package Azure.AI.OpenAI
// dotnet add package Azure.Identity

// Your .csproj will then include:
// <PackageReference Include="Azure.AI.OpenAI" Version="2.1.0" />
// <PackageReference Include="Azure.Identity" Version="1.13.0" />

The Azure.Identity package is what enables passwordless authentication with Microsoft Entra ID — a best practice we'll use shortly.

Step 2: Your First GPT-4o Chat Completion in C#

Let's start with the simplest working example. This creates an Azure OpenAI client and sends a single prompt to your GPT-4o deployment.

using Azure.AI.OpenAI;
using OpenAI.Chat;
using System.ClientModel;

string endpoint = "https://your-resource.openai.azure.com/";
string apiKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY")!;
string deploymentName = "gpt-4o"; // your deployment name, not the model name

// Create the top-level Azure OpenAI client
AzureOpenAIClient azureClient = new(
    new Uri(endpoint),
    new ApiKeyCredential(apiKey));

// Get a chat client scoped to your GPT-4o deployment
ChatClient chatClient = azureClient.GetChatClient(deploymentName);

// Send a chat completion request
ChatCompletion completion = await chatClient.CompleteChatAsync(
    new SystemChatMessage("You are a helpful C# coding assistant."),
    new UserChatMessage("Explain dependency injection in one sentence."));

Console.WriteLine(completion.Content[0].Text);

That's it — you've just called GPT-4o from C#. The SystemChatMessage sets the model's behavior, while the UserChatMessage carries the actual prompt. Notice we pull the API key from an environment variable rather than hard-coding it — never commit secrets to source control.

Step 3: Use Entra ID Authentication (Recommended Best Practice)

API keys work, but the gold-standard for production Azure OpenAI C# apps is keyless authentication using managed identities. This removes secrets from your codebase entirely.

using Azure.AI.OpenAI;
using Azure.Identity;
using OpenAI.Chat;

string endpoint = "https://your-resource.openai.azure.com/";
string deploymentName = "gpt-4o";

// DefaultAzureCredential automatically uses managed identity in Azure,
// or your local az login / Visual Studio credentials during development
AzureOpenAIClient azureClient = new(
    new Uri(endpoint),
    new DefaultAzureCredential());

ChatClient chatClient = azureClient.GetChatClient(deploymentName);

ChatCompletion completion = await chatClient.CompleteChatAsync(
    new UserChatMessage("Give me a fun fact about the C# language."));

Console.WriteLine(completion.Content[0].Text);

Why this matters: With DefaultAzureCredential, the same code runs locally (using your developer login) and in production (using a managed identity) with no changes. You assign the Cognitive Services OpenAI User role to the identity, and there are zero keys to rotate, leak, or accidentally push to GitHub.

Step 4: Maintain Conversation Context (Multi-Turn Chat)

GPT-4o is stateless — it doesn't remember previous messages unless you send them back. To build a chatbot, you maintain a list of messages and append each turn.

using OpenAI.Chat;

var messages = new List<ChatMessage>
{
    new SystemChatMessage("You are a concise .NET expert."),
    new UserChatMessage("What is a record type in C#?")
};

ChatCompletion first = await chatClient.CompleteChatAsync(messages);
Console.WriteLine(first.Content[0].Text);

// Add the assistant's reply back into the history, then ask a follow-up
messages.Add(new AssistantChatMessage(first));
messages.Add(new UserChatMessage("How is it different from a class?"));

ChatCompletion second = await chatClient.CompleteChatAsync(messages);
Console.WriteLine(second.Content[0].Text);

The model now answers the follow-up with full awareness of the prior exchange. Be mindful that every message counts toward your token limit and cost — for long conversations, trim or summarize older turns.

Step 5: Stream Responses for a Better User Experience

For chat interfaces, waiting several seconds for a full response feels slow. Streaming sends tokens as they're generated, letting you render text in real time — exactly how ChatGPT feels.

using OpenAI.Chat;

await foreach (StreamingChatCompletionUpdate update
    in chatClient.CompleteChatStreamingAsync(
        new UserChatMessage("Write a short haiku about C# async programming.")))
{
    foreach (ChatMessageContentPart part in update.ContentUpdate)
    {
        Console.Write(part.Text);
    }
}
Console.WriteLine();

Streaming dramatically improves perceived performance. In an ASP.NET Core app you'd pipe these chunks to the client over Server-Sent Events (SSE) or SignalR.

Step 6: Control Output with Completion Options

Production code should tune the model's behavior rather than relying on defaults. The most important option is Temperature (creativity vs. determinism) and MaxOutputTokenCount (cost and latency control).

using OpenAI.Chat;

var options = new ChatCompletionOptions
{
    Temperature = 0.2f,          // lower = more focused and deterministic
    MaxOutputTokenCount = 500,   // cap response length to control cost
    TopP = 0.95f
};

ChatCompletion completion = await chatClient.CompleteChatAsync(
    new[] { new UserChatMessage("Summarize SOLID principles in 3 bullets.") },
    options);

Console.WriteLine(completion.Content[0].Text);

// Inspect token usage for cost monitoring
Console.WriteLine($"Prompt tokens: {completion.Usage.InputTokenCount}");
Console.WriteLine($"Output tokens: {completion.Usage.OutputTokenCount}");

For factual, deterministic tasks (data extraction, classification) use a low temperature like 0.0–0.3. For creative writing, push it toward 0.7–1.0.

Wiring It into ASP.NET Core with Dependency Injection

In a real .NET application you'll register the client once via DI rather than newing it up per request. Here's the clean, production-friendly pattern:

// Program.cs
using Azure.AI.OpenAI;
using Azure.Identity;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton(sp =>
{
    string endpoint = builder.Configuration["AzureOpenAI:Endpoint"]!;
    return new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential());
});

var app = builder.Build();

app.MapPost("/ask", async (AzureOpenAIClient client, string prompt) =>
{
    var chat = client.GetChatClient("gpt-4o");
    var result = await chat.CompleteChatAsync(new UserChatMessage(prompt));
    return Results.Ok(result.Value.Content[0].Text);
});

app.Run();

Registering AzureOpenAIClient as a singleton is correct and recommended — the client is thread-safe and designed to be reused, which improves connection pooling and performance.

Common Pitfalls When Integrating GPT-4o into .NET

  • Confusing deployment name with model name — In code you reference the deployment name you chose in the portal, which may or may not match "gpt-4o". This is the #1 cause of 404 "deployment not found" errors.
  • Hard-coding API keys — Use environment variables, Azure Key Vault, or managed identities. Never commit keys.
  • Ignoring rate limits (429 errors) — Azure OpenAI enforces tokens-per-minute quotas. Implement exponential backoff and retry; the SDK includes some retry logic, but high-traffic apps need their own throttling strategy.
  • Sending unbounded conversation history — Token costs grow with every turn. Cap or summarize history to control spend and avoid context-length errors.
  • Not setting MaxOutputTokenCount — Runaway responses cost money and add latency. Always set a sensible cap.
  • Blocking calls — Always use the Async methods so you don't exhaust thread-pool threads under load.

Best Practices for Production Azure OpenAI C# Apps

  • Use managed identities for keyless auth in every non-local environment.
  • Store configuration (endpoint, deployment name) in appsettings.json or Key Vault, never in code.
  • Monitor token usage from the Usage property and log it to track cost per feature.
  • Add resilience with Polly for retries and circuit breakers around transient failures.
  • Validate and sanitize user input to defend against prompt injection.
  • Pick the right region for data residency in the UK, Canada, Australia, or India.

Conclusion: Key Takeaways

Integrating Azure OpenAI with C# gives you enterprise-grade, secure access to GPT-4o directly inside your .NET application. In this tutorial you learned how to install the SDK, authenticate with both API keys and Entra ID, run chat completions, maintain conversation context, stream responses, and apply the completion options that matter most in production.

The key takeaways:

  • Use the Azure.AI.OpenAI SDK and reference your deployment name, not the model name.
  • Prefer managed identity authentication over API keys for secure, keyless access.
  • Register AzureOpenAIClient as a singleton and call the async methods.
  • Always set temperature and max output tokens, and monitor token usage to control cost.
  • Handle rate limits with retries and trim conversation history for scalability.

You now have a solid, production-ready foundation to integrate GPT-4o into any .NET app. Start small with a single chat completion, then layer in streaming, DI, and resilience as you scale. Happy coding!

About csharp-coder.com
Your go-to resource for C#, .NET, and modern software development. Follow along for daily tutorials, tips, and real-world examples.

Comments

Popular posts from this blog

Angular 14 CRUD Operation with Web API .Net 6.0

How to Perform CRUD Operation Using Angular 14 In this article, we will learn the angular crud (create, read, update, delete) tutorial with ASP.NET Core 6 web API. We will use the SQL Server database and responsive user interface for our Web app, we will use the Bootstrap 5. Let's start step by step. Step 1 - Create Database and Web API First we need to create Employee database in SQL Server and web API to communicate with database. so you can use my previous article CRUD operations in web API using net 6.0 to create web API step by step. As you can see, after creating all the required API and database, our API creation part is completed. Now we have to do the angular part like installing angular CLI, creating angular 14 project, command for building and running angular application...etc. Step 2 - Install Angular CLI Now we have to install angular CLI into our system. If you have already installed angular CLI into your system then skip this step.  To install angular CLI ope...

Angular 14 : 404 error during refresh page after deployment

In this article, We will learn how to solve 404 file or directory not found angular error in production.  Refresh browser angular 404 file or directory not found error You have built an Angular app and created a production build with ng build --prod You deploy it to a production server. Everything works fine until you refresh the page. The app throws The requested URL was not found on this server message (Status code 404 not found). It appears that angular routing not working on the production server when you refresh the page. The error appears on the following scenarios When you type the URL directly in the address bar. When you refresh the page The error appears on all the pages except the root page.   Reason for the requested URL was not found on this server error In a Multi-page web application, every time the application needs to display a page it has to send a request to the web server. You can do that by either typing the URL in the address bar, clicking on the Me...

Send an Email via SMTP with MailKit Using .NET 6

How to Send an Email in .NET Core This tutorial show you how to send an email in .NET 6.0 using the MailKit email client library. Install MailKit via NuGet Visual Studio Package Manager Console: Install-Package MailKit How to Send an HTML Email in .NET 6.0 This code sends a simple HTML email using the Gmail SMTP service. There are instructions further below on how to use a few other popular SMTP providers - Gmail, Hotmail, Office 365. // create email message var email = new MimeMessage(); email.From.Add(MailboxAddress.Parse("from_address@example.com")); email.To.Add(MailboxAddress.Parse("to_address@example.com")); email.Subject = "Email Subject"; email.Body = new TextPart(TextFormat.Html) { Text = "<h1>Test HTML Message Body</h1>" }; // send email using var smtp = new SmtpClient(); smtp.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls); smtp.Authenticate("[Username]", "[Password]"); smtp.Se...