ASP.NET Core コンタクト フォームの統合 (最小限の API と Razor)
IHttpClientFactory、サーバー側 API キー、自動冪等キーを使用して、問い合わせフォームの送信を ASP.NET Core Minimal API または Razor Pages から Lugatu に安全に転送します。
1. IHttpClientFactory を使用した最小限の API エンドポイント
ASP.NET Core Minimal API は、コンタクト フォームの送信を受信し、IHttpClientFactory と冪等性キーを使用して Lugatu に安全に転送するクリーンで高性能な方法を提供します。
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.appsettings.json での構成
ASP.NET Core 構成プロバイダーを使用して、Lugatu 資格情報を安全に保存します。 運用環境では、Azure Key Vault、AWS Secrets Manager、または環境変数を利用します。
{
"Lugatu": {
"FormId": "YOUR_FORM_GUID",
"ApiKey": "lug_live_your_secret_server_key"
}
}
3. Razor ページ コントローラーの実装
従来の複数ページの ASP.NET Core MVC または Razor Pages アプリの場合、ASP.NET Core に組み込まれた偽造防止トークン検証のメリットを利用しながら、OnPostAsync 内でフォーム送信を転送します。
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();
}
}
セキュリティと認証の不変性
技術的な不変条件: サーバー間の API キー (lug_live_...) はバックエンドで厳密に保持される必要があります。 それらを appsettings.json または Secrets Vault に保存します。 ライブキーをクライアントブラウザに送信しないでください。
トラブルシューティングと一般的な取り込みエラー
API キーが lug_live_ で始まり、Authorization: Bearer ヘッダーに渡されていることを確認します。 API キーが対象のフォーム ID を含むワークスペースに属していることを確認してください。
よくある質問
新しい HttpClient インスタンスを作成するのではなく、IHttpClientFactory を使用する必要があるのはなぜですか?
IHttpClientFactory はソケット プーリングを管理し、ASP.NET Core アプリケーションの高負荷時のソケットの枯渇を防ぎます。
フォームエンドポイントを作成する準備はできましたか?
数秒で無料で始められます。 クレジットカードは必要ありません。