How do you integrate an AI chat model such as OpenAI into an ASP.NET Core application?

Asked yesterday Updated yesterday 42 views

1 Answer


1

Yes. The cleanest modern approach is to put OpenAI behind an ASP.NET Core API endpoint, keep the API key on the server, and use OpenAI's official .NET SDK to call the Responses API. OpenAI's official .NET repository includes an ASP.NET Core example using ResponsesClient and dependency injection. 

1. Overall architecture

A typical implementation looks like this:

Browser / Mobile App
        |
        | POST /api/chat
        v
ASP.NET Core Web API
        |
        | User message
        v
Chat Service
        |
        | OpenAI SDK
        v
OpenAI Responses API
        |
        | AI response
        v
ASP.NET Core
        |
        v
Browser / Mobile App

The important point is that the browser should not call OpenAI directly with your secret API key. Your ASP.NET Core backend should make the OpenAI request.

2. Install the OpenAI .NET SDK

The official OpenAI .NET SDK is available as an open-source repository.  

For example:

dotnet add package OpenAI

You can then use the SDK's ResponsesClient.

The current official ASP.NET Core example uses configuration-based registration and dependency injection.

3. Store the API key securely

For local development, don't put the API key directly into source code.

For example, use .NET User Secrets:

dotnet user-secrets init

dotnet user-secrets set \
  "Clients:ResponsesClient:Credential:Key" \
  "YOUR_OPENAI_API_KEY"

Or use an environment variable:

Clients__ResponsesClient__Credential__Key=YOUR_OPENAI_API_KEY

OpenAI's official ASP.NET Core example specifically demonstrates both environment variables and .NET User Secrets. 

For production, you can use a proper secret-management solution such as Azure Key Vault rather than committing credentials to appsettings.json.

4. Configure appsettings.json

For example:

{
  "Clients": {
    "ResponsesClient": {
      "Model": "gpt-5.5"
    }
  }
}

Keep the actual API key outside the source-controlled configuration file.

The model can then be changed through configuration rather than hard-coded throughout your application.

5. Register the OpenAI client

In Program.cs:

using OpenAI.Responses;

var builder = WebApplication.CreateBuilder(args);

builder.AddResponsesClient("Clients:ResponsesClient");

builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();

app.Run();

AddResponsesClient is provided by the OpenAI .NET integration and binds the configured ResponsesClient to ASP.NET Core's dependency-injection system. The official sample registers the client this way and treats it as thread-safe for the application's lifetime.

6. Create a Chat API

Create a request model:

public class ChatRequest
{
    public string Message { get; set; } = string.Empty;
}

Then create a controller:

using Microsoft.AspNetCore.Mvc;
using OpenAI.Responses;

[ApiController]
[Route("api/chat")]
public class ChatController : ControllerBase
{
    private readonly ResponsesClient _client;
    private readonly IConfiguration _configuration;

    public ChatController(
        ResponsesClient client,
        IConfiguration configuration)
    {
        _client = client;
        _configuration = configuration;
    }

    [HttpPost]
    public async Task<IActionResult> Chat(ChatRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Message))
        {
            return BadRequest("Message is required.");
        }

        var model =
            _configuration["Clients:ResponsesClient:Model"]
            ?? throw new InvalidOperationException(
                "OpenAI model is not configured.");

        var response =
            await _client.CreateResponseAsync(
                model,
                request.Message);

        return Ok(new
        {
            response = response.GetOutputText()
        });
    }
}

This is essentially the same pattern demonstrated in OpenAI's official ASP.NET Core example: inject ResponsesClient, read the configured model, call CreateResponseAsync, and return the generated output.

7. Call the API from your frontend

Your frontend could send:

POST /api/chat
Content-Type: application/json

{
    "message": "Explain dependency injection in ASP.NET Core."
}

The ASP.NET Core API sends the message to OpenAI and might return:

{
  "response": "Dependency Injection (DI) is a design pattern..."
}

Your React, Angular, Blazor, MVC, or mobile application can then display that response as a chat message.

8. Add conversation history

A real chatbot needs more than one independent question.

For example:

User:     What is ASP.NET Core?
AI:       ASP.NET Core is Microsoft's web framework...

User:     What language does it use?
AI:       It primarily uses C#...

The second question requires context from the first interaction.

You therefore need some form of conversation state.

A simple architecture is:

User
 |
 +-- ConversationId
 |
 v
ASP.NET Core
 |
 +-- Load previous messages
 |
 +-- Add new user message
 |
 v
OpenAI
 |
 +-- Generate response
 |
 v
Save conversation

For a production application, conversation data might be stored in:

  • SQL Server
  • PostgreSQL
  • Redis
  • Cosmos DB

another persistent data store

The current OpenAI API also supports mechanisms for continuing responses, so you don't necessarily have to manually reconstruct every conversation in every scenario. 

9. Don't expose the OpenAI key

This is one of the most important security rules.

Don't do this

const apiKey = "sk-...";

inside your browser application.

Do this

Browser
   |
   | /api/chat
   v
ASP.NET Core
   |
   | OpenAI API key
   v
OpenAI

The API key remains on your server.

You should also add:

  • Authentication
  • Authorization
  • Rate limiting
  • Request validation
  • Logging
  • Usage limits

Input/output filtering where appropriate

10. Create a dedicated AI service

For a larger application, I wouldn't put OpenAI logic directly in the controller.

Instead:

ChatController
      |
      v
IChatService
      |
      v
OpenAIChatService
      |
      v
ResponsesClient

For example:

public interface IChatService
{
    Task<string> GetResponseAsync(string message);
}

Implementation:

using OpenAI.Responses;

public class OpenAIChatService : IChatService
{
    private readonly ResponsesClient _client;
    private readonly IConfiguration _configuration;

    public OpenAIChatService(
        ResponsesClient client,
        IConfiguration configuration)
    {
        _client = client;
        _configuration = configuration;
    }

    public async Task<string> GetResponseAsync(string message)
    {
        var model =
            _configuration["Clients:ResponsesClient:Model"]
            ?? throw new InvalidOperationException(
                "AI model is not configured.");

        var response =
            await _client.CreateResponseAsync(model, message);

        return response.GetOutputText();
    }
}

Register it:

builder.Services.AddScoped<IChatService, OpenAIChatService>();

Then your controller becomes much simpler:

[ApiController]
[Route("api/chat")]
public class ChatController : ControllerBase
{
    private readonly IChatService _chatService;

    public ChatController(IChatService chatService)
    {
        _chatService = chatService;
    }

    [HttpPost]
    public async Task<IActionResult> Chat(ChatRequest request)
    {
        var answer =
            await _chatService.GetResponseAsync(request.Message);

        return Ok(new
        {
            response = answer
        });
    }
}

This separation becomes particularly valuable when you later add RAG, function calling, conversation storage, moderation, streaming, logging, or multiple AI providers.

Production architecture

For an enterprise .NET application, I'd typically evolve it toward:

                  ┌─────────────────┐
                  │ React / Blazor  │
                  │ Angular / Mobile│
                  └────────┬────────┘
                           │
                           ▼
                  ┌─────────────────┐
                  │ ASP.NET Core API│
                  └────────┬────────┘
                           │
                    Authentication
                    Rate Limiting
                    Validation
                           │
                           ▼
                  ┌─────────────────┐
                  │   Chat Service  │
                  └────────┬────────┘
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
        Conversation     RAG / DB    AI Tools
           Store          Search
              │            │            │
              └────────────┼────────────┘
                           ▼
                  ┌─────────────────┐
                  │ OpenAI Responses│
                  │       API       │
                  └─────────────────┘

In short

The basic implementation is:

ASP.NET Core → OpenAI .NET SDK → Responses API → return AI response to frontend.

The official OpenAI .NET SDK currently provides a dedicated ResponsesClient, and OpenAI's own ASP.NET Core sample demonstrates dependency-injection-based registration.

For a real application, I'd strongly recommend not stopping at the basic API call. The next important pieces are conversation memory, streaming responses, authentication/rate limiting, error handling, logging, and eventually RAG if the chatbot needs to answer questions from your company's own data.

OpenAI .NET SDK on GitHub

Write Your Answer