Configuration — appsettings.json, environment, User Secrets, IOptions

~20 daq · .NET Backend · ASP.NET Core — Kirish

Muammodan boshlaylik

var connStr = "Host=localhost;Database=dokon;Username=postgres;Password=12345";
var jwtKalit = "mening-maxfiy-kalitim";
var smtpServer = "smtp.mail.uz";

Muammolar:

  • Production da boshqa baza — kodni o'zgartirib, qayta build qilish
  • Parol va maxfiy kalit — git da, repozitoriyga kirgan har kim ko'radi
  • Development, staging va production uchun har xil qiymatlar — qayerda saqlash?

Konfiguratsiya manbalari

ASP.NET Core sozlamalarni bir nechta manbadan o'qiydi va ularni ustma-ust qo'yadi. Keyingi manba oldingisini ustidan yozadi:

1. appsettings.json                    ← umumiy standart qiymatlar
2. appsettings.{Environment}.json      ← muhitga xos (Development, Production)
3. User Secrets                        ← faqat Development, lokal maxfiy qiymatlar
4. Environment o'zgaruvchilari          ← server, Docker, bulut
5. Buyruq qatori argumentlari           ← eng yuqori ustuvorlik

WebApplication.CreateBuilder(args) bularning hammasini avtomatik ulaydi (37-dars).


Hayotiy o'xshatma

Kiyim qatlamlari. Asosiy kiyim — hamma kun uchun (appsettings.json). Ob-havoga qarab ustidan kurtka (appsettings.Production.json). Cho'ntakdagi kalitlar — faqat sizda, hech kimga ko'rsatilmaydi (User Secrets, environment). Eng ustki qatlam — ko'rinadigani.


appsettings.json

{
  "ConnectionStrings": {
    "Default": "Host=localhost;Database=dokon;Username=postgres"
  },
  "Jwt": {
    "Issuer": "dokon-api",
    "Audience": "dokon-app",
    "MuddatDaqiqa": 60
  },
  "Xabar": {
    "Kanal": "email",
    "Smtp": {
      "Server": "smtp.mail.uz",
      "Port": 587
    }
  },
  "Logging": {
    "LogLevel": { "Default": "Information" }
  }
}

O'qish — IConfiguration

var config = builder.Configuration;

string? conn = config.GetConnectionString("Default");      // ConnectionStrings:Default
string? kanal = config["Xabar:Kanal"];                     // ichma-ich — ":" bilan
int port = config.GetValue<int>("Xabar:Smtp:Port");        // tur bilan
int muddat = config.GetValue("Jwt:MuddatDaqiqa", 30);      // standart qiymat bilan

Muhitlar

appsettings.json                 ← hammasi uchun
appsettings.Development.json     ← lokal
appsettings.Production.json      ← server
// appsettings.Development.json
{
  "Logging": { "LogLevel": { "Default": "Debug" } }
}

Muhit — ASPNETCORE_ENVIRONMENT o'zgaruvchisidan (standart — Production). Lokal — launchSettings.json da Development.

if (builder.Environment.IsDevelopment()) { }
if (app.Environment.IsProduction()) { }

User Secrets — lokal maxfiy qiymatlar

dotnet user-secrets init
dotnet user-secrets set "ConnectionStrings:Default" "Host=localhost;Database=dokon;Username=postgres;Password=12345"
dotnet user-secrets set "Jwt:Kalit" "development-uchun-kamida-32-belgili-tasodifiy-kalit"
dotnet user-secrets list
  • Qiymatlar loyiha papkasida emas, foydalanuvchi profilida (%APPDATA%\Microsoft\UserSecrets\...) saqlanadi — git ga tushmaydi
  • Faqat Development muhitida avtomatik o'qiladi
  • Kodda — oddiy config["Jwt:Kalit"]

[!WARNING] appsettings.json ga hech qachon parol, API kalit, JWT kaliti yozmang — u git da. Lokal — User Secrets, server — environment o'zgaruvchilari yoki secret manager (Azure Key Vault, AWS Secrets Manager, 82-dars). Maxfiy qiymat git tarixiga tushgan bo'lsa — faylni o'chirish yetmaydi, kalitni almashtiring.


Environment o'zgaruvchilari

Ichma-ich kalitlar uchun : o'rniga ikki pastki chiziq __:

# Linux / Docker
export ConnectionStrings__Default="Host=db;Database=dokon;Username=app;Password=..."
export Jwt__Kalit="production-kaliti"
export ASPNETCORE_ENVIRONMENT=Production
# docker-compose.yml (81-dars)
environment:
  - ConnectionStrings__Default=Host=db;Database=dokon;Username=app;Password=${DB_PAROL}

Options pattern — turlangan sozlamalar

Sozlamalarni string kalitlar bilan tarqoq o'qish o'rniga — klass:

public class JwtSozlamalari
{
    public const string Bolim = "Jwt";

    public required string Issuer { get; init; }
    public required string Audience { get; init; }
    public required string Kalit { get; init; }
    public int MuddatDaqiqa { get; init; } = 60;
}
// Program.cs
builder.Services
    .AddOptions<JwtSozlamalari>()
    .Bind(builder.Configuration.GetSection(JwtSozlamalari.Bolim))
    .Validate(s => s.Kalit.Length >= 32, "Jwt:Kalit kamida 32 belgi bo'lishi kerak")
    .ValidateOnStart();
public class TokenService(IOptions<JwtSozlamalari> options)
{
    private readonly JwtSozlamalari _jwt = options.Value;

    public string Yarat(Foydalanuvchi u)
    {
        var tugash = DateTime.UtcNow.AddMinutes(_jwt.MuddatDaqiqa);
        // ...
        return "";
    }
}
  • Turlangan, avtomatik to'ldirish, xato yozilgan kalit — kompilyatsiya xatosi
  • ValidateOnStart() — noto'g'ri sozlama bo'lsa ilova ishga tushmaydi (birinchi so'rovda emas)
  • DataAnnotations bilan ham: .ValidateDataAnnotations() + property larda [Required], [Range]
Interfeys Xususiyati
IOptions<T> Bir marta o'qiladi (singleton) — ko'pchilik holatlar
IOptionsSnapshot<T> Har so'rovda qayta o'qiladi (scoped)
IOptionsMonitor<T> Fayl o'zgarganda yangilanadi, o'zgarish hodisasi bilan

[!TIP] Sozlamalar ilova ishga tushganda tekshirilsin: noto'g'ri connection string yoki qisqa kalit bilan ilova "ishga tushib", birinchi foydalanuvchi so'rovida yiqilgandan ko'ra — darhol, aniq xabar bilan to'xtagani yaxshi.


Tez-tez uchraydigan xatolar

Maxfiy qiymatni appsettings.json da saqlash — git ga tushadi.

Environment o'zgaruvchisida : ishlatish — Linux da ishlamaydi; __.

Kalitni xato yozish — jim null:

var k = config["Jwt:Kalitt"];    // null, xato yo'q

Options pattern + ValidateOnStart.

Production da ASPNETCORE_ENVIRONMENT o'rnatilmagan — standart Production (to'g'ri), lekin staging serverda Staging ni o'rnatishni unutish.


Xulosa

Konfiguratsiya qatlamlari: appsettings.json → appsettings.{Env}.json → User Secrets (Development) → environment o'zgaruvchilari → buyruq qatori; keyingisi ustun. O'qish — config["A:B"], GetValue<T>, GetConnectionString.

Muhit — ASPNETCORE_ENVIRONMENT. Maxfiy qiymatlar — hech qachon appsettings da: lokal — dotnet user-secrets, server — environment (A__B) yoki secret manager. Options pattern — turlangan klass, Bind, Validate, ValidateOnStart, IOptions<T>.


Keyingi bo'lim

41-dars: Controller — [ApiController], [Route], ControllerBase