Integrate Groq AI API with ASP.NET Core MVC: Complete Step-by-Step Tutorial
Build your own AI-powered web application using C#, an MVC Controller, Razor Views, and the Groq API. Learn the complete integration process with practical code examples.
Want to add Artificial Intelligence to your .NET web application? In this tutorial, we will learn how to integrate a Large Language Model (LLM) into an ASP.NET Core MVC application using the Groq API.
We will build a simple AI assistant where users can enter a question in a web form, submit it to a Groq-hosted AI model, and display the generated response directly on the Razor View.
An AI-powered web application that accepts a question, sends it from a C# MVC Controller to Groq, receives the AI-generated response, and displays it on the same webpage.
📚 Table of Contents
1. Prerequisites
Before starting, make sure you have the following installed or available:
- Visual Studio or Visual Studio Code.
- .NET SDK compatible with your project.
- Basic knowledge of C# and ASP.NET Core MVC.
- Basic understanding of HTML and Razor Views.
- A Groq account and an API key.
Get started using these official resources:
- Download the .NET SDK
- Open Groq Console
- Explore available Groq models
- Read Groq API compatibility documentation
2. Understand the Architecture
Before writing code, understand how the different components communicate.
Here is the complete request-response flow:
- The user enters a question into the web form.
- The form submits the question to the MVC Controller.
- The controller prepares an HTTP request containing the model name and messages.
- The request is sent to the Groq API over HTTPS.
- The selected AI model generates a response.
- The controller extracts the generated text.
- The response is assigned to the ViewModel and returned to the Razor View.
Controller as its base class. We are not creating a separate API Controller for this demonstration.
3. Create an ASP.NET Core MVC Project
Open a terminal and execute the following commands:
dotnet new mvc -n GroqAIMvc
cd GroqAIMvc
Open the project in your preferred editor.
Your project structure will look like this:
GroqAIMvc/
├── Controllers/
│ └── HomeController.cs
├── Models/
│ └── AIViewModel.cs
├── Views/
│ └── Home/
│ └── Index.cshtml
├── appsettings.json
├── Program.cs
└── GroqAIMvc.csproj
We will create or update these files one by one.
4. Get and Configure Your Groq API Key
Open the Groq Console, sign in, and create an API key according to the available account options.
For this local development example, configure the key in PowerShell:
$env:GROQ_API_KEY = "YOUR_GROQ_API_KEY"
Replace the placeholder with your actual API key. This environment variable applies to the current PowerShell session.
Verify that the variable is set:
$env:GROQ_API_KEY
HomeController.cs, appsettings.json, or a public repository. Use a secure secret store or environment variable.
5. Configure appsettings.json
Open appsettings.json and add the Groq configuration.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Groq": {
"BaseUrl": "https://api.groq.com/openai/v1/",
"Model": "openai/gpt-oss-20b"
}
}
Understanding the configuration:
| Setting | Purpose |
|---|---|
| BaseUrl | The base address for Groq's OpenAI-compatible API. |
| Model | The identifier of the model used to generate responses. |
The model identifier shown above is an example. Confirm that it is available to your account by checking the official model documentation.
6. Create the Model Class — AIViewModel.cs
Create a new class named AIViewModel.cs inside the Models folder.
using System.ComponentModel.DataAnnotations;
namespace GroqAIMvc.Models
{
public class AIViewModel
{
[Required(ErrorMessage = "Please enter your question.")]
[Display(Name = "Ask AI")]
[StringLength(10000, MinimumLength = 1)]
public string Question { get; set; } = string.Empty;
public string Answer { get; set; } = string.Empty;
}
}
What does this class do?
Questionstores the question submitted by the user.Answerstores the response generated by the AI model.[Required]enables server-side validation against missing values.[StringLength]limits the accepted question length.
The ViewModel carries the data between the View and the Controller.
7. Create HomeController.cs
Now comes the most important part of our project: integrating the Groq API inside a normal ASP.NET Core MVC Controller.
Open Controllers/HomeController.cs and replace its contents with the following code.
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
using GroqAIMvc.Models;
using Microsoft.AspNetCore.Mvc;
namespace GroqAIMvc.Controllers
{
public class HomeController : Controller
{
private readonly HttpClient _httpClient;
private readonly IConfiguration _configuration;
private readonly ILogger<HomeController> _logger;
public HomeController(
IHttpClientFactory httpClientFactory,
IConfiguration configuration,
ILogger<HomeController> logger)
{
_httpClient = httpClientFactory.CreateClient();
_configuration = configuration;
_logger = logger;
}
[HttpGet]
public IActionResult Index()
{
return View(new AIViewModel());
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(
AIViewModel model,
CancellationToken cancellationToken)
{
if (!ModelState.IsValid)
{
return View(model);
}
string? apiKey =
Environment.GetEnvironmentVariable("GROQ_API_KEY");
if (string.IsNullOrWhiteSpace(apiKey))
{
ModelState.AddModelError(
string.Empty,
"The AI service is not configured.");
return View(model);
}
string baseUrl =
_configuration["Groq:BaseUrl"]
?? "https://api.groq.com/openai/v1/";
string modelName =
_configuration["Groq:Model"]
?? "openai/gpt-oss-20b";
var requestData = new GroqRequest
{
Model = modelName,
Messages = new List<GroqMessage>
{
new GroqMessage
{
Role = "system",
Content =
"You are a helpful AI assistant. " +
"Explain technical concepts clearly " +
"with practical examples."
},
new GroqMessage
{
Role = "user",
Content = model.Question
}
}
};
try
{
using var request = new HttpRequestMessage(
HttpMethod.Post,
new Uri(
new Uri(baseUrl),
"chat/completions"));
request.Headers.Authorization =
new AuthenticationHeaderValue(
"Bearer",
apiKey);
request.Content = JsonContent.Create(requestData);
using var response = await _httpClient.SendAsync(
request,
cancellationToken);
if (!response.IsSuccessStatusCode)
{
_logger.LogWarning(
"Groq returned HTTP status {StatusCode}.",
(int)response.StatusCode);
ModelState.AddModelError(
string.Empty,
"The AI provider could not process your request. Please try again.");
return View(model);
}
var result =
await response.Content
.ReadFromJsonAsync<GroqResponse>(
cancellationToken: cancellationToken);
model.Answer =
result?.Choices?
.FirstOrDefault()?
.Message?.Content
?? "No response was generated.";
return View(model);
}
catch (OperationCanceledException)
when (cancellationToken.IsCancellationRequested)
{
throw;
}
catch (OperationCanceledException)
{
ModelState.AddModelError(
string.Empty,
"The AI request timed out. Please try again.");
return View(model);
}
catch (HttpRequestException ex)
{
_logger.LogError(ex, "Groq HTTP request failed.");
ModelState.AddModelError(
string.Empty,
"Unable to connect to the AI service.");
return View(model);
}
catch (System.Text.Json.JsonException ex)
{
_logger.LogError(ex, "Invalid response received from Groq.");
ModelState.AddModelError(
string.Empty,
"The AI provider returned an unexpected response.");
return View(model);
}
}
private sealed class GroqRequest
{
[JsonPropertyName("model")]
public string Model { get; set; } = string.Empty;
[JsonPropertyName("messages")]
public List<GroqMessage> Messages { get; set; }
= new List<GroqMessage>();
}
private sealed class GroqMessage
{
[JsonPropertyName("role")]
public string Role { get; set; } = string.Empty;
[JsonPropertyName("content")]
public string Content { get; set; } = string.Empty;
}
private sealed class GroqResponse
{
[JsonPropertyName("choices")]
public List<GroqChoice>? Choices { get; set; }
}
private sealed class GroqChoice
{
[JsonPropertyName("message")]
public GroqResponseMessage? Message { get; set; }
}
private sealed class GroqResponseMessage
{
[JsonPropertyName("content")]
public string? Content { get; set; }
}
}
}
Understand the Controller step by step
Step 1: Inject IHttpClientFactory
public HomeController(
IHttpClientFactory httpClientFactory,
IConfiguration configuration,
ILogger<HomeController> logger)
{
_httpClient = httpClientFactory.CreateClient();
_configuration = configuration;
_logger = logger;
}
Dependency injection supplies the HTTP client factory, configuration, and logger. We use the HTTP client to send requests to the external AI service.
Step 2: Display the initial page
[HttpGet]
public IActionResult Index()
{
return View(new AIViewModel());
}
When the user visits the page, the GET action creates an empty ViewModel and passes it to the Razor View.
Step 3: Receive the user's question
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(
AIViewModel model,
CancellationToken cancellationToken)
The POST action receives the submitted form data. ASP.NET Core model binding maps the form fields to the properties of AIViewModel.
Step 4: Prepare the request
var requestData = new GroqRequest
{
Model = modelName,
Messages = new List<GroqMessage>
{
new GroqMessage
{
Role = "system",
Content = "You are a helpful AI assistant."
},
new GroqMessage
{
Role = "user",
Content = model.Question
}
}
};
The system message provides instructions to the model. The user message contains the question that the model needs to answer.
Step 5: Send the request to Groq
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", apiKey);
request.Content = JsonContent.Create(requestData);
using var response = await _httpClient.SendAsync(
request,
cancellationToken);
The API key is sent in the HTTP Authorization header. The request body is serialized to JSON and sent over HTTPS.
Step 6: Extract the AI-generated response
model.Answer =
result?.Choices?
.FirstOrDefault()?
.Message?.Content
?? "No response was generated.";
return View(model);
The controller extracts the generated text, assigns it to model.Answer, and returns the populated ViewModel to the same View.
8. Configure Program.cs
Open Program.cs and ensure that MVC and HttpClient services are registered.
var builder = WebApplication.CreateBuilder(args);
// Register MVC services
builder.Services.AddControllersWithViews();
// Register IHttpClientFactory
builder.Services.AddHttpClient();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Unable to resolve service for type 'System.Net.Http.IHttpClientFactory', make sure builder.Services.AddHttpClient(); is present before builder.Build().
The AddHttpClient() method registers the services required to resolve IHttpClientFactory through dependency injection.
If you are using a newer MVC project template with MapStaticAssets(), you can retain the static asset configuration generated by your template. The essential part of this example is the MVC and HTTP client service registration.
9. Design the Razor View — Index.cshtml
Now we will create the user interface. The page contains a question box, a submit button, validation messages, and an AI response section.
Open Views/Home/Index.cshtml and use the following code:
@model GroqAIMvc.Models.AIViewModel
@{
ViewData["Title"] = "Groq AI Assistant";
}
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-9 col-lg-8">
<div class="card shadow-lg border-0 rounded-4">
<div class="card-header bg-primary text-white p-4">
<h2 class="mb-1">Groq AI Assistant</h2>
<p class="mb-0">
Ask a question and get an AI-generated answer.
</p>
</div>
<div class="card-body p-4">
<form asp-controller="Home"
asp-action="Index"
method="post">
@Html.AntiForgeryToken()
<div asp-validation-summary="ModelOnly"
class="text-danger mb-3">
</div>
<div class="mb-3">
<label asp-for="Question"
class="form-label fw-bold">
Enter Your Question
</label>
<textarea asp-for="Question"
class="form-control"
rows="4"
placeholder="Example: Explain AI and Machine Learning."></textarea>
<span asp-validation-for="Question"
class="text-danger">
</span>
</div>
<button type="submit"
class="btn btn-primary btn-lg w-100">
Ask Groq AI
</button>
</form>
@if (!string.IsNullOrWhiteSpace(Model.Answer))
{
<hr class="my-4" />
<div class="card border-success">
<div class="card-header bg-success text-white">
<h5 class="mb-0">AI Response</h5>
</div>
<div class="card-body">
<div class="ai-answer">@Model.Answer</div>
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
<style>
body {
background-color: #f3f6fb;
}
textarea.form-control {
resize: vertical;
min-height: 120px;
}
.ai-answer {
white-space: pre-wrap;
overflow-wrap: anywhere;
line-height: 1.8;
font-size: 16px;
}
</style>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
How does the View display the answer?
@if (!string.IsNullOrWhiteSpace(Model.Answer))
{
<div class="ai-answer">@Model.Answer</div>
}
When the controller assigns the generated response to Model.Answer, the Razor View displays the text on the page.
Razor automatically HTML-encodes the value, so the response is treated as text instead of executable HTML. The CSS property white-space: pre-wrap preserves line breaks in the answer.
10. Run and Test the Application
Open your terminal and run the application:
dotnet restore
dotnet build
dotnet run
Open the local URL displayed in your terminal. For example, your application might run at:
https://localhost:7001
The port above is only an example. Use the actual URL shown in your terminal.
Enter this question in the text area:
Explain the difference between Artificial Intelligence and Machine Learning. Give practical examples suitable for college students.
Click Ask Groq AI. If your API key, model, and request are configured correctly, the AI-generated answer will appear below the form.
Test the application with these questions
- What is ASP.NET Core MVC?
- Explain Dependency Injection in C#.
- What is the difference between AI and Machine Learning?
- Explain async and await in C# with an example.
- Generate five .NET interview questions with answers.
11. Common Errors and Solutions
| Error | Possible cause | What to check |
|---|---|---|
| 401 Unauthorized | Missing or invalid API key. | Check the GROQ_API_KEY environment variable. |
| 400 Bad Request | Invalid request fields or unsupported parameters. | Check the request payload and API documentation. |
| 404 Not Found | Incorrect endpoint or model identifier. | Verify the base URL and model availability. |
| 429 Too Many Requests | Rate or usage limit reached. | Check account limits and retry policy. |
| IHttpClientFactory not resolved | HTTP client services were not registered. | Add builder.Services.AddHttpClient();. |
| AI service unavailable | Network, DNS, TLS, or provider issue. | Check connectivity and provider status. |
| Empty AI response | No usable response text was returned. | Inspect the response structure and provider documentation. |
For further debugging, refer to the official Groq API reference.
12. How Can You Improve This Project?
Once the basic application works, you can extend it into a more complete AI product.
For a production application, also consider request limits, timeouts, structured logging, monitoring, and the applicable API usage policies.
13. Frequently Asked Questions
Q1. Can we integrate Groq AI with ASP.NET Core MVC?
Yes. An MVC Controller can send HTTP requests to Groq's API, receive the model response, and pass the generated text to a Razor View.
Q2. Do we need an API Controller for this application?
No. This tutorial uses a normal MVC Controller that returns Views. A separate API Controller is not required for the form-based application.
Q3. Why do we use IHttpClientFactory?
IHttpClientFactory provides managed HttpClient instances and supports centralized configuration and handler lifetime management. Register it using builder.Services.AddHttpClient().
Q4. Where should the Groq API key be stored?
Use an environment variable, development secret storage, or a managed secret store. Never expose the API key in browser-side JavaScript or public source code.
Q5. Can we use the same approach for other AI providers?
Yes, if the provider supports a compatible API format. You may need to change the endpoint, model identifier, authentication, and request or response structure.
Q6. Does the application remember previous questions?
No. The basic example sends the current question with the system instructions. To build a conversational chatbot, you must store and send relevant conversation history.
14. Conclusion
In this tutorial, we learned how to integrate the Groq API with an ASP.NET Core MVC web application using C# and Razor Views.
We created a ViewModel, configured the API settings, implemented a normal MVC Controller, registered IHttpClientFactory, sent a request to Groq, and displayed the generated answer on the same webpage.
This project demonstrates an important concept for modern .NET developers: your ASP.NET Core application can use an external Large Language Model to add AI capabilities without requiring you to train a model yourself.
Keep Learning. Keep Building.
Practice C#, ASP.NET Core, Web API, Cloud, and modern AI integration by building real-world projects.
Explore More Learning Resources →Technical note: API availability, supported models, request parameters, usage limits, and pricing can change. Check the official Groq documentation before deploying your application.

0 Comments
POST Answer of Questions and ASK to Doubt