Get up and running with the Noundry platform in minutes. Choose your path and build amazing .NET applications faster than ever before.
Build a modern web application with authentication, data access, and beautiful UI components.
These examples use the Noundry CLI (nd), which wraps dotnet commands with beautiful UI and progress tracking.
Install: dotnet tool install --global Noundry.Cli
This creates a new ASP.NET Core web application and installs the essential Noundry components for web development.
Skip manual package installation! Use our pre-configured web app template:
Includes Noundry.UI, Authnz, Tuxedo, and DotEnvX pre-configured!
Update your Program.cs file:
using Noundry.DotEnvX.Core.Extensions;
using Noundry.Authnz.Extensions;
using Noundry.Tuxedo.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Load environment variables
builder.Configuration.AddDotEnvX();
// Add services
builder.Services.AddRazorPages();
builder.Services.AddTuxedoSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
builder.Services.AddNoundryOAuth(builder.Configuration);
builder.Services.AddNoundryUI();
var app = builder.Build();
// Configure pipeline
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseNoundryOAuth();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Create a .env file:
# Database
DATABASE_URL=Server=localhost;Database=MyApp;Integrated Security=true;TrustServerCertificate=true;
# OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
Update appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "${DATABASE_URL}"
},
"OAuth": {
"Providers": {
"google": {
"ClientId": "${GOOGLE_CLIENT_ID}",
"ClientSecret": "${GOOGLE_CLIENT_SECRET}"
}
}
}
}
First, add TagHelper support to _ViewImports.cshtml:
@using MyApp
@namespace MyApp.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Noundry.UI
@addTagHelper *, Noundry.Authnz
Also include Elements for client-side form validation in your layout:
Then create Pages/Index.cshtml with Noundry components:
@page
@model IndexModel
<div class="max-w-4xl mx-auto py-8">
<h1 class="text-4xl font-bold text-gray-900 mb-8">Welcome to My App</h1>
<!-- Authentication Status -->
<noundry-oauth-status show-when-anonymous="true">
<noundry-oauth-login show-all="true"></noundry-oauth-login>
</noundry-oauth-status>
<noundry-oauth-status show-when-authenticated="true">
<noundry-card>
<h2>Welcome back!</h2>
<noundry-oauth-status show-name="true" show-email="true"></noundry-oauth-status>
</noundry-card>
</noundry-oauth-status>
<!-- Success Alert -->
<noundry-alert type="success" title="Success!">
Your Noundry application is running!
</noundry-alert>
</div>
<!-- Toast Container -->
<noundry-toast-container position="top-right" />
Wrap your forms with Noundry Elements for instant validation:
<noundry-element>
<form asp-action="Submit" method="post">
<input type="email" name="email" required
data-error="Valid email required">
<button type="submit">Submit</button>
</form>
</noundry-element>
Automatic validation with beautiful error messages!
Visit https://localhost:7001 and you'll see your application with:
You've successfully created a modern web application with the Noundry platform.
Build a high-performance API with advanced data access and environment management.
Get a fully-configured REST API with Noundry components:
Includes Tuxedo, Bowtie, DotEnvX, and Guardian pre-configured!
Create Models/Product.cs:
using Noundry.Tuxedo.Contrib;
using Noundry.Tuxedo.Bowtie.Attributes;
[Table("Products")]
public class Product
{
[Key]
public int Id { get; set; }
[Column(MaxLength = 200)]
[Index("IX_Products_Name")]
public string Name { get; set; } = string.Empty;
[Column(Precision = 18, Scale = 2)]
[CheckConstraint("Price > 0")]
public decimal Price { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
Bowtie automatically synchronizes your database schema from your C# models. No manual SQL scripts needed!
โ Creates Tables
From [Table] attributes
๐ Adds Indexes
From [Index] attributes
๐ก๏ธ Enforces Constraints
From [CheckConstraint] attributes
Your database is now in sync with your code! Run bowtie sync whenever you modify your models.
Create Controllers/ProductsController.cs:
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IDbConnection _connection;
public ProductsController(IDbConnection connection)
{
_connection = connection;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Product>>> GetProducts()
{
var products = await _connection.GetAllAsync<Product>();
return Ok(products);
}
[HttpPost]
public async Task<ActionResult<Product>> CreateProduct(Product product)
{
// Validate using Guardian
product.Name = Guard.Against.NullOrWhiteSpace(product.Name);
product.Price = Guard.Against.NegativeOrZero(product.Price);
var id = await _connection.InsertAsync(product);
var created = await _connection.GetAsync<Product>(id);
return CreatedAtAction(nameof(GetProduct), new { id }, created);
}
}
Run nd dn run and visit /swagger to test your API.
Add robust testing and validation to any .NET application in minutes.
using Noundry.Assertive;
using Guardian;
using Xunit;
public class ProductTests
{
[Fact]
public void Product_WithValidData_ShouldBeCreated()
{
// Arrange & Act
var product = new Product
{
Name = Guard.Against.NullOrWhiteSpace("Test Product"),
Price = Guard.Against.NegativeOrZero(29.99m)
};
// Assert using Assertive
product.Assert()
.IsNotNull()
.Satisfies(p => p.Name == "Test Product")
.Satisfies(p => p.Price == 29.99m);
}
}
You now have fluent, readable test assertions and comprehensive input validation!
Import CSV files with Slurp or generate realistic test data with Cufflink
Import a CSV file with automatic schema inference:
100,000+ rows per second on modern hardware
Automatically detects column types and constraints
SQL Server, PostgreSQL, MySQL, SQLite
Auto-creates indexes on key columns
Need realistic test data? Cufflink generates fake data while automatically maintaining FK/PK relationships!
Generate realistic data for any table with automatic relationship handling:
โจ Cufflink automatically detects PK/FK relationships and generates valid references!
Automatically maintains FK/PK integrity across tables
Built-in generators for names, emails, addresses, and more
Works with SQL Server, PostgreSQL, MySQL, SQLite
Generate thousands of records in seconds with custom patterns
Use Slurp for importing CSVs and Cufflink for generating test data.
Unified AI Gateway for .NET - Access OpenAI, Anthropic, Google Gemini, and more through a single, consistent API with automatic failover and streaming support.
# Install the AI Gateway client library
dotnet add package Noundry.AIG.Client
using Noundry.AIG.Client;
using Noundry.AIG.Client.Builders;
using Noundry.AIG.Client.Configuration;
using Noundry.AIG.Core.Extensions;
using Noundry.AIG.Core.Models;
using Noundry.AIG.Providers;
// Configure the client
var httpClientFactory = new SimpleHttpClientFactory();
var providerFactory = new ProviderFactory(httpClientFactory);
var options = new AigClientOptions
{
UseLocalProviders = true,
ProviderConfigs = new Dictionary<string, ProviderConfig>
{
["openai"] = new ProviderConfig
{
ApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY")
},
["anthropic"] = new ProviderConfig
{
ApiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY")
}
}
};
var aigClient = new AigClient(providerFactory, options);
// Send a request using PromptBuilder
var prompt = new PromptBuilder()
.WithModel("anthropic/claude-sonnet-4")
.WithTemperature(0.7f)
.AddSystemMessage("You are a helpful AI assistant.")
.AddUserMessage("Explain quantum computing in simple terms.")
.Build();
var response = await aigClient.SendAsync(prompt);
Console.WriteLine(response.GetTextContent());
Build complex prompts with a clean, intuitive fluent API that provides IntelliSense support and type safety.
var prompt = new PromptBuilder()
.WithModel("openai/gpt-4")
.AddUserMessage("What are primary colors?")
.Build();
var response = await aigClient.SendAsync(prompt);
var prompt = new PromptBuilder()
.WithModel("anthropic/claude-sonnet-4")
.WithTemperature(0.8f)
.WithMaxTokens(2000)
.WithTopP(0.9f)
.AddSystemMessage("You are creative.")
.AddUserMessage("Write a story.")
.Build();
Chain multiple AI calls where the output of one prompt automatically feeds into the next, creating powerful multi-step workflows.
// Create a chain that generates, writes, and translates content
var chain = new ChainPromptBuilder()
.WithDefaultModel("anthropic/claude-sonnet-4")
// Step 1: Generate a random topic
.AddStep("Generate Topic", _ =>
new PromptBuilder()
.AddUserMessage("Give me a random creative writing topic."))
// Step 2: Write about the topic (uses previous output)
.AddStep("Write Content", previousOutput =>
new PromptBuilder()
.AddUserMessage($"Write a short paragraph about: {previousOutput}"))
// Step 3: Translate to Spanish
.AddStep("Translate", previousOutput =>
new PromptBuilder()
.WithModel("openai/gpt-4") // Can use different models per step
.AddUserMessage($"Translate to Spanish:\n{previousOutput}"));
// Execute the chain
var result = await chain.ExecuteAsync(aigClient);
if (result.Success)
{
Console.WriteLine($"Final output: {result.FinalOutput}");
// Inspect each step
foreach (var step in result.Steps)
{
Console.WriteLine($"{step.StepName}: {step.Output}");
}
}
Automatically try multiple providers in order for high availability. The gateway uses the first successful response.
// Try multiple providers in preferred order
var prompt = new PromptBuilder()
.WithModels(
"openai/gpt-4", // Try OpenAI first
"anthropic/claude-sonnet-4", // Fall back to Anthropic
"google/gemini-pro" // Finally try Google
)
.AddUserMessage("Generate a creative story idea.")
.Build();
var multiResponse = await aigClient.SendMultiAsync(prompt);
Console.WriteLine($"Received {multiResponse.Responses.Count} responses");
Console.WriteLine($"Time taken: {multiResponse.TotalDurationMs}ms");
// Get the first successful response
if (multiResponse.HasSuccess && multiResponse.FirstSuccess != null)
{
Console.WriteLine($"Response from: {multiResponse.FirstSuccess.Provider}");
Console.WriteLine(multiResponse.FirstSuccess.GetTextContent());
}
// Or compare all responses
foreach (var resp in multiResponse.Responses)
{
var status = resp.IsSuccess() ? "Success" : $"Failed - {resp.Error?.Message}";
Console.WriteLine($"- {resp.Model}: {status}");
}
Stream responses in real-time for better user experience and reduced perceived latency.
var streamingPrompt = new PromptBuilder()
.WithModel("openai/gpt-4")
.WithStreaming(true)
.AddUserMessage("Write a short story about a time traveler.")
.Build();
Console.Write("Response: ");
// Stream the response as it's generated
await foreach (var chunk in aigClient.SendStreamAsync(streamingPrompt))
{
if (chunk.IsSuccess())
{
var text = chunk.GetTextContent();
if (!string.IsNullOrEmpty(text))
{
Console.Write(text); // Print as it arrives
}
}
}
Console.WriteLine();
Access OpenAI, Anthropic, Google, and more through a unified interface.
Try multiple providers in order with automatic fallback.
Real-time response streaming from all supported providers.
Intuitive API for building complex prompts with type safety.
Chain multiple prompts where output feeds into next input.
Production-ready with HttpClientFactory and concurrent operations.
Continue your journey with Noundry platform and explore advanced features.
Explore TagHelpers and server-side UI components for ASP.NET Core.
View ComponentsExplore the complete Noundry platform with detailed information about each library and component.
View LibrariesDive deep into comprehensive documentation with API references, advanced examples, and best practices.
Read Documentation