Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In deze quickstart bouw je een ASP.NET Core minimale API met Microsoft.Data.SqlClient 7.1.1.
Je begint met een lege map, de .NET SDK en een SQL Server- of Azure SQL-database die je vanaf je computer kunt bereiken. Je eindigt met een web-API die een bericht toevoegt aan een tabel en het terugleest via ID.
Daarbij doet de app het volgende:
- Leest zijn verbindingsreeks uit de ASP.NET Core-configuratie. Voor lokale ontwikkeling komt de waarde van gebruikersgeheimen, dus het blijft buiten je projectmap.
- Registreert een dataklasse met afhankelijkheidsinjectie.
- Opent en sluit een verbinding voor elk verzoek, waardoor de standaardverbindingspool fysieke verbindingen kan hergebruiken.
- Geeft de
CancellationTokenvan het verzoek door aan elke databaseaanroep.
De app gebruikt dezelfde dbo.SqlClientQuickstart tabel als Quickstart: Verbind en vraag op met Microsoft.Data.SqlClient. Je kunt eerst een van beide quickstarts doen.
Prerequisites
- Vereist: de .NET 10 SDK of een later ondersteunde .NET SDK. De SDK draait op Windows, Linux en macOS.
- Een database waarmee je verbinding kunt maken. Om er een te maken, zie je de vereisten in de console quickstart.
-
curlof PowerShell gebruiken om verzoeken naar de API te sturen.
De huidige ASP.NET Core draait op .NET, niet op het .NET Framework. Om de driver van .NET Framework te gebruiken, zie .NET Framework projecten.
De database-identiteit heeft toestemming nodig om verbinding te maken en om een tabel te maken, in te voegen en te selecteren.
Het project maken
Voer in een lege map deze commando's uit:
dotnet new web --framework net10.0 --name SqlClientWebQuickstart
cd SqlClientWebQuickstart
dotnet add package Microsoft.Data.SqlClient --version 7.1.1
dotnet add package Microsoft.Data.SqlClient.Extensions.Azure --version 7.1.1
dotnet user-secrets init
dotnet user-secrets init voegt een UserSecretsId toe aan het projectbestand. ASP.NET Core laadt gebruikersgeheimen alleen wanneer de app in de Development omgeving draait, wat de standaard is voor dotnet run.
Het extensiepakket levert de Microsoft Entra-authenticatiemodi van het stuurprogramma. Als je app alleen SQL-authenticatie gebruikt, kun je Microsoft.Data.SqlClient.Extensions.Azure weglaten. Als je beide pakketten gebruikt, houd dan hun versies hetzelfde.
Configureer de verbinding
Sla de verbindingsreeks op als ConnectionStrings:Quickstart in user secrets. Gebruikersgeheimen worden opgeslagen in je gebruikersprofiel, niet in de projectmap, dus ze worden niet ingecheckt in versiebeheer. Plaats geen wachtwoord of productieverbindingsreeks in appsettings.json.
Kies een van deze startpunten en vervang de placeholders. De dotnet user-secrets set commando's gebruiken enkele aanhalingstekens voor PowerShell en Bash. Gebruik in de opdrachtprompt dubbele aanhalingstekens, omdat de opdrachtprompt enkele aanhalingstekens opslaat als onderdeel van de sleutel en waarde.
Azure SQL with Microsoft Entra ID
Log in met een Microsoft Entra-identiteit die toegang heeft tot de database. Voor lokale ontwikkeling gebruik je een ontwikkelaarstool zoals de Azure CLI:
az login
Sla daarna de verbindingsreeks op. Kopieer de exacte server- en databasenamen uit de Azure SQL-database. Dezelfde verbindingsreeks werkt voor de SQL-database in Microsoft Fabric wanneer je de server- en databasenamen van het SQL-databaseitem gebruikt, zoals beschreven in de console quickstart.
dotnet user-secrets set 'ConnectionStrings:Quickstart' 'Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;Connect Timeout=30'
Deze verbindingsreeks bevat geen secret.
Active Directory Default gebruikt je ontwikkelaarsaanmelding lokaal. Wanneer je uitrolt naar Azure App Service of Azure Container Apps, verleen je de beheerde identiteit van de app toegang tot de database, verander je de waarde naar Authentication=Active Directory Managed Identity, en stel je deze als ConnectionStrings__Quickstart in in de configuratie van de host. Voor andere opties, zie Microsoft Entra-authenticatie met Microsoft.Data.SqlClient.
Lokale SQL Server met SQL-authenticatie
Sla de verbindingsreeks op voor een lokale ontwikkelinstantie die geen vertrouwd certificaat heeft. Gebruik enkele aanhalingstekens om te voorkomen dat PowerShell en Bash een $ teken in het wachtwoord interpreteren.
dotnet user-secrets set 'ConnectionStrings:Quickstart' 'Server=tcp:<server>,1433;Database=<database>;User ID=<user-id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'
Caution
TrustServerCertificate=true Slaat servercertificaatvalidatie over. Gebruik het alleen met een lokale ontwikkelingsinstantie. Voor gedeelde of productie-SQL Server-instanties installeer je een certificaat dat de client vertrouwt en verwijder TrustServerCertificate=true. Zie Versleuteling en certificaatvalidatie in Microsoft.Data.SqlClientvoor meer informatie.
Code toevoegen
Vervang de inhoud van Program.cs met deze code:
using System.Data;
using Microsoft.Data.SqlClient;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<MessageStore>();
var app = builder.Build();
await app.Services.GetRequiredService<MessageStore>()
.EnsureTableAsync(app.Lifetime.ApplicationStopping);
app.MapPost("/messages", async (
NewMessage input, MessageStore store, CancellationToken cancellationToken) =>
{
if (string.IsNullOrWhiteSpace(input.Text) || input.Text.Length > 200)
{
return Results.BadRequest("Text must be 1 to 200 characters.");
}
Message message = await store.AddAsync(input.Text, cancellationToken);
return Results.Created($"/messages/{message.Id}", message);
});
app.MapGet("/messages/{id:int}", async (
int id, MessageStore store, CancellationToken cancellationToken) =>
await store.GetAsync(id, cancellationToken) is Message message
? Results.Ok(message)
: Results.NotFound());
app.Run();
record NewMessage(string Text);
record Message(int Id, string Text, DateTimeOffset CreatedAt);
sealed class MessageStore(IConfiguration configuration)
{
private readonly string _connectionString =
configuration.GetConnectionString("Quickstart")
?? throw new InvalidOperationException(
"Set the ConnectionStrings:Quickstart configuration value.");
public async Task EnsureTableAsync(CancellationToken cancellationToken)
{
const string sql = """
IF OBJECT_ID(N'dbo.SqlClientQuickstart', N'U') IS NULL
BEGIN
CREATE TABLE dbo.SqlClientQuickstart
(
Id int IDENTITY(1, 1) PRIMARY KEY,
Message nvarchar(200) NOT NULL,
CreatedAt datetimeoffset NOT NULL
CONSTRAINT DF_SqlClientQuickstart_CreatedAt
DEFAULT sysdatetimeoffset()
);
END;
""";
await using var connection = new SqlConnection(_connectionString);
await connection.OpenAsync(cancellationToken);
await using var command =
new SqlCommand(sql, connection) { CommandTimeout = 30 };
await command.ExecuteNonQueryAsync(cancellationToken);
}
public async Task<Message> AddAsync(
string text, CancellationToken cancellationToken)
{
const string sql = """
INSERT INTO dbo.SqlClientQuickstart (Message)
OUTPUT INSERTED.Id, INSERTED.Message, INSERTED.CreatedAt
VALUES (@message);
""";
await using var connection = new SqlConnection(_connectionString);
await connection.OpenAsync(cancellationToken);
await using var command =
new SqlCommand(sql, connection) { CommandTimeout = 30 };
command.Parameters.Add("@message", SqlDbType.NVarChar, 200).Value = text;
await using SqlDataReader reader =
await command.ExecuteReaderAsync(cancellationToken);
await reader.ReadAsync(cancellationToken);
return new Message(
reader.GetInt32(0), reader.GetString(1), reader.GetDateTimeOffset(2));
}
public async Task<Message?> GetAsync(
int id, CancellationToken cancellationToken)
{
const string sql = """
SELECT Id, Message, CreatedAt
FROM dbo.SqlClientQuickstart
WHERE Id = @id;
""";
await using var connection = new SqlConnection(_connectionString);
await connection.OpenAsync(cancellationToken);
await using var command =
new SqlCommand(sql, connection) { CommandTimeout = 30 };
command.Parameters.Add("@id", SqlDbType.Int).Value = id;
await using SqlDataReader reader =
await command.ExecuteReaderAsync(cancellationToken);
return await reader.ReadAsync(cancellationToken)
? new Message(
reader.GetInt32(0), reader.GetString(1), reader.GetDateTimeOffset(2))
: null;
}
}
De app uitvoeren
Start de app op een vaste poort:
dotnet run --urls http://localhost:5000
Bij het opstarten maakt de app de tabel aan als die niet bestaat. Wanneer de app klaar is, bevat de output deze regels:
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
Als de app de database niet kan bereiken, stopt hij bij het opstarten met een SqlException. Voor veelvoorkomende oorzaken, zie Probleemoplossing.
De API aanroepen
Laat de app draaien en open een tweede terminal. Voeg een bericht toe met een POST-verzoek, en lees het vervolgens terug via ID met een GET-verzoek. Als de tabel al rijen heeft, bijvoorbeeld van de console-quickstart, vervang 1 dan in het GET-verzoek door de id die je POST-verzoek teruggeeft.
Voor PowerShell:
Invoke-RestMethod -Method Post -Uri http://localhost:5000/messages -ContentType application/json -Body (@{ text = 'Hello from ASP.NET Core' } | ConvertTo-Json)
Invoke-RestMethod http://localhost:5000/messages/1
PowerShell formateert elke JSON-respons als een tabel. De eerste rij is het 201 Created antwoord op het POST-verzoek, en de tweede rij is het GET-antwoord:
id text createdAt
-- ---- ---------
1 Hello from ASP.NET Core 2026-10-21T00:04:43.3588978+00:00
1 Hello from ASP.NET Core 2026-10-21T00:04:43.3588978+00:00
Windows PowerShell 5.1 toont createdAt als de string die de API teruggeeft. PowerShell 7 zet het om naar een datum in lokale tijd, zoals 10/20/2026 7:04:43 PM.
In Windows PowerShell curl is een alias voor Invoke-WebRequest, dat de curl-opties niet accepteert. Gebruik de PowerShell-commando's, of start curl.exe via de opdrachtprompt.
Voor de opdrachtprompt:
curl -X POST http://localhost:5000/messages -H "Content-Type: application/json" -d "{\"text\":\"Hello from ASP.NET Core\"}"
curl http://localhost:5000/messages/1
De opdrachtprompt behandelt enkele aanhalingstekens niet als aanhalingstekens, dus gebruikt het JSON-lichaam dubbele aanhalingstekens die met backslashes zijn ontsnapt. Elk commando geeft de JSON-respons weer:
{"id":1,"text":"Hello from ASP.NET Core","createdAt":"2026-10-21T00:05:15.4936763+00:00"}
{"id":1,"text":"Hello from ASP.NET Core","createdAt":"2026-10-21T00:05:15.4936763+00:00"}
Voor Bash:
curl -X POST http://localhost:5000/messages -H "Content-Type: application/json" -d '{"text":"Hello from ASP.NET Core"}'
curl http://localhost:5000/messages/1
{"id":1,"text":"Hello from ASP.NET Core","createdAt":"2026-10-20T20:44:17.8634925+00:00"}
{"id":1,"text":"Hello from ASP.NET Core","createdAt":"2026-10-20T20:44:17.8634925+00:00"}
Je ID's en tijdstempels verschillen. Als je eerst de console quickstart hebt uitgevoerd, lopen de ID's door vanaf die rijen. Een verzoek om een ID dat niet bestaat geeft 404 Not Found terug. Een leeg bericht geeft 400 Bad Request terug.
Druk op Ctrl+C in de eerste terminal om de app te stoppen.
Hoe de code werkt
- De app registreert
MessageStoreals singleton. Het bevat alleen de verbindingsreeks, die het één keer uitIConfigurationleest. De verbinding blijft niet behouden. - Elke methode maakt een
SqlConnection, opent het, voert één commando uit en ruimt het op metawait using. Bij het opruimen wordt de fysieke verbinding teruggegeven aan de verbindingspool en hergebruikt het volgende verzoek deze. Connection pooling staat standaard aan, dus je hoeft het niet te configureren. Voor afstemmingsopties, zie SQL Server connection pooling met Microsoft.Data.SqlClient. - ASP.NET Core bindt de parameter
CancellationTokenaan de aanvraag. Als de client de verbinding verbreekt, annuleert het token het openen, het commando en het lezen. - De parameters
@iden@messagekomen overeen met de kolomtypen en -grootten. De API valideert de berichtlengte voordat de API de waarde naar de database stuurt. -
OUTPUT INSERTED.Id, INSERTED.Message, INSERTED.CreatedAtgeeft de ingevoegde rij terug, inclusief de door de server gegenereerde ID en tijdstempel, zonder een tweede query. - In andere omgevingen leest ASP.NET Core dezelfde
ConnectionStrings:Quickstartsleutel uit omgevingsvariabelen, zoalsConnectionStrings__Quickstart, of van een andere configuratieprovider, zoals Azure Key Vault.
Troubleshoot
| Fout of symptoom | Wat u moet controleren | Meer informatie |
|---|---|---|
Set the ConnectionStrings:Quickstart configuration value. |
De app vond de verbindingsreeks niet. Voer dotnet user-secrets list uit in de projectmap en controleer of de app in de Development-omgeving draait. |
Veilige opslag van app-geheimen tijdens ontwikkeling in ASP.NET Core |
System.ArgumentException: Cannot find an authentication provider for 'ActiveDirectoryDefault' Bij de start |
De verbindingsreeks gebruikt een Active Directory authenticatiemodus, maar het project verwijst niet naar Microsoft.Data.SqlClient.Extensions.Azure. Voeg het pakket toe met dezelfde versie als Microsoft.Data.SqlClient. |
Microsoft Entra-authenticatie verplaatst zich in 7.0 naar een extensiepakket |
SqlException Bij de start |
De app kon geen verbinding maken of de tabel aanmaken. Het foutnummer geeft de oorzaak aan, zoals 18456 voor een mislukte login. | Probleemoplossing in de console quickstart |
415 Unsupported Media Type |
Het verzoek stelt Content-Type: application/json niet in. |
Minimal APIs beknopte naslaggids |
Cannot bind parameter 'Headers' |
Je voerde het curl-commando uit in Windows PowerShell, waarin curlInvoke-WebRequest uitvoert. Gebruik de PowerShell-opdrachten in De API aanroepen. |
Invoke-RestMethod |
''' is an invalid start of a value |
Je voerde het Bash curl-commando uit in de opdrachtprompt, die de enkele aanhalingstekens als onderdeel van de body stuurt. Gebruik de opdrachtpromptcommando's in De API aanroepen. | Roep de API aan |
De hulpbronnen opschonen
Verwijder de tabel met een willekeurige query tool:
DROP TABLE IF EXISTS dbo.SqlClientQuickstart;
Verwijder de opgeslagen verbindingsreeks. Voer vanuit de projectmap uit:
dotnet user-secrets clear
Verwijder daarna de projectmap. Voer vanuit de oudermap het volgende commando uit in PowerShell:
Remove-Item -Recurse -Force SqlClientWebQuickstart
Voor Bash:
rm -rf SqlClientWebQuickstart