Home / Guides / ASP.NET Core Contact Form Integration (Minimal APIs & Razor)
INTEGRATION GUIDE · .NET & BACKEND

ASP.NET Core Contact Form Integration (Minimal APIs & Razor)

Forward contact form submissions securely from ASP.NET Core Minimal APIs or Razor Pages to Lugatu using IHttpClientFactory, server-side API keys, and automatic idempotency keys.

1. Minimal API Endpoint with IHttpClientFactory

ASP.NET Core Minimal APIs provide a clean, high-performance way to receive contact form submissions and forward them securely to Lugatu using IHttpClientFactory and an Idempotency-Key.

Program.cs csharp
using System.Net.Http.Headers;
using System.Text.Json;

var builder = WebApplication.CreateBuilder(args);

// Register resilient Lugatu HTTP client
builder.Services.AddHttpClient("Lugatu", client =>
{
    client.BaseAddress = new Uri("https://www.lugatu.com");
    client.DefaultRequestHeaders.Authorization =
        new AuthenticationHeaderValue("Bearer", builder.Configuration["Lugatu:ApiKey"]);
});

var app = builder.Build();

app.MapPost("/api/contact", async (ContactRequest request, IHttpClientFactory clientFactory, IConfiguration config) =>
{
    // 1. Silent rejection for automated bot traps
    if (!string.IsNullOrEmpty(request.Gotcha))
    {
        return Results.Ok(new { success = true });
    }

    var client = clientFactory.CreateClient("Lugatu");
    var formId = config["Lugatu:FormId"];

    var payload = new
    {
        fields = new Dictionary<string, string?>
        {
            ["name"] = request.Name,
            ["email"] = request.Email,
            ["message"] = request.Message,
        }
    };

    using var message = new HttpRequestMessage(HttpMethod.Post, $"/api/v1/forms/{formId}/submissions")
    {
        Content = new StringContent(JsonSerializer.Serialize(payload), System.Text.Encoding.UTF8, "application/json")
    };

    // Ensure at-most-once delivery with Idempotency-Key
    message.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());

    var response = await client.SendAsync(message);
    if (!response.IsSuccessStatusCode)
    {
        return Results.StatusCode((int)response.StatusCode);
    }

    return Results.Ok(new { success = true });
});

app.Run();

public record ContactRequest(string Name, string Email, string Message, string? Gotcha);

2. Configuration in appsettings.json

Store your Lugatu credentials securely using ASP.NET Core configuration providers. In production, utilize Azure Key Vault, AWS Secrets Manager, or environment variables.

appsettings.json json
{
  "Lugatu": {
    "FormId": "YOUR_FORM_GUID",
    "ApiKey": "lug_live_your_secret_server_key"
  }
}

3. Razor Pages Controller Implementation

For traditional multi-page ASP.NET Core MVC or Razor Pages apps, forward form submissions within OnPostAsync while benefiting from ASP.NET Core built-in Antiforgery token verification.

Pages/Contact.cshtml.cs csharp
public class ContactModel : PageModel
{
    private readonly IHttpClientFactory _clientFactory;
    private readonly string _formId;

    public ContactModel(IHttpClientFactory clientFactory, IConfiguration config)
    {
        _clientFactory = clientFactory;
        _formId = config["Lugatu:FormId"]!;
    }

    [BindProperty]
    public ContactInput Input { get; set; } = new();

    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid || !string.IsNullOrEmpty(Input.Gotcha))
        {
            return Page();
        }

        var client = _clientFactory.CreateClient("Lugatu");
        var content = new StringContent(
            JsonSerializer.Serialize(new { fields = Input }),
            System.Text.Encoding.UTF8,
            "application/json");

        content.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());

        var res = await client.PostAsync($"/api/v1/forms/{_formId}/submissions", content);
        if (res.IsSuccessStatusCode)
        {
            return RedirectToPage("/ContactSuccess");
        }

        ModelState.AddModelError(string.Empty, "Unable to deliver inquiry. Please try again.");
        return Page();
    }
}

Security & Authentication Invariant

Technical Invariant: Server-to-server API keys (lug_live_...) must be kept strictly on the backend. Store them in appsettings.json or secrets vaults; never transmit live keys to client browsers.

Troubleshooting & Common Ingestion Errors

HTTP 401 Unauthorized response from Lugatu API

Verify that your API key starts with lug_live_ and is passed in the Authorization: Bearer header. Ensure the API key belongs to the workspace containing the targeted form ID.

Frequently Asked Questions

Why should I use IHttpClientFactory rather than creating a new HttpClient instance?

IHttpClientFactory manages socket pooling and prevents socket exhaustion under heavy load in ASP.NET Core applications.

Ready to create your form endpoint?

Get started for free in seconds. No credit card required.

Start Free →