Menulis Perisian Tengah Tersuai
Cipta perisian tengah sebaris dengan Use/Run/Map dan perisian tengah berasaskan kelas dengan InvokeAsync untuk komponen yang boleh digunakan semula.
Menulis Perisian Tengah Tersuai ialah pelajaran Akademi C# percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Akademi C#, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Akademi C# merangkumi sejumlah 4 pelajaran.
Mengapakah Perisian Tengah Tersuai?
Perisian tengah tersuai mengendalikan perkara rentas fungsi yang terpakai pada banyak permintaan: pengelogan, pemasaan, pengendalian ralat, pengesahan, pemampatan, dan pencaching. Menulisnya sekali bermakna logik itu berjalan secara automatik untuk setiap permintaan yang sepadan.
Perisian Tengah Sebaris dengan Use
Cara terpantas untuk menambahkan perisian tengah: hantarkan wakil kepada app.Use(). Ini sesuai untuk prototaip atau logik yang benar-benar mudah.
app.Use(async (context, next) =>
{
var start = DateTimeOffset.UtcNow;
await next(context);
var elapsed = DateTimeOffset.UtcNow - start;
context.Response.Headers.Append(
"X-Elapsed", elapsed.TotalMilliseconds.ToString("F0") + "ms");
});Perisian Tengah Berasaskan Kelas (Konvensyen)
Kelas perisian tengah konvensional mempunyai pembina yang menerima RequestDelegate dan kaedah awam InvokeAsync. Parameter pembina tambahan boleh disuntik daripada DI.
public class SecurityHeadersMiddleware
{
private readonly RequestDelegate _next;
public SecurityHeadersMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
var headers = context.Response.Headers;
headers.Append("X-Content-Type-Options", "nosniff");
headers.Append("X-Frame-Options", "DENY");
headers.Append("X-XSS-Protection", "1; mode=block");
headers.Append("Referrer-Policy", "strict-origin-when-cross-origin");
await _next(context);
}
}
// Extension method for clean registration:
public static class SecurityHeadersExtensions
{
public static IApplicationBuilder UseSecurityHeaders(
this IApplicationBuilder app) =>
app.UseMiddleware<SecurityHeadersMiddleware>();
}IMiddleware untuk Kebergantungan Berskop DI
Jika perisian tengah anda memerlukan perkhidmatan berskop, seperti DbContext, laksanakan IMiddleware. Daftarkannya sebagai Scoped, dan rangka kerja akan menyelesaikannya semula untuk setiap permintaan.
public class AuditMiddleware : IMiddleware
{
private readonly AuditDbContext _db;
private readonly IHttpContextAccessor _http;
public AuditMiddleware(AuditDbContext db, IHttpContextAccessor http)
{
_db = db;
_http = http;
}
public async Task InvokeAsync(HttpContext ctx, RequestDelegate next)
{
await next(ctx);
if (ctx.Request.Method != "GET")
{
_db.AuditLogs.Add(new AuditLog
{
User = ctx.User.Identity?.Name,
Path = ctx.Request.Path,
Status = ctx.Response.StatusCode,
At = DateTime.UtcNow
});
await _db.SaveChangesAsync();
}
}
}
builder.Services.AddScoped<AuditMiddleware>();
app.UseMiddleware<AuditMiddleware>();Perisian Tengah dengan Pilihan
Hantarkan konfigurasi kepada perisian tengah melalui objek pilihan dalam pembina. Daftarkan pilihan itu dengan bekas DI atau hantarkannya sebaris apabila mendaftarkan perisian tengah.
public class ThrottleOptions
{
public int MaxRequestsPerSecond { get; set; } = 100;
public string[] ExcludedPaths { get; set; } = Array.Empty<string>();
}
public class ThrottleMiddleware
{
private readonly RequestDelegate _next;
private readonly ThrottleOptions _options;
public ThrottleMiddleware(RequestDelegate next, ThrottleOptions options)
{
_next = next;
_options = options;
}
// ...
}
// Registration with options:
app.UseMiddleware<ThrottleMiddleware>(new ThrottleOptions
{
MaxRequestsPerSecond = 50
});Perisian Tengah Pengendalian Pengecualian
Perisian tengah pengendali pengecualian tersuai menangkap semua pengecualian yang tidak dikendalikan dan mengembalikan respons ralat berstruktur.
public class GlobalExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<GlobalExceptionMiddleware> _logger;
public GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> l)
{
_next = next;
_logger = l;
}
public async Task InvokeAsync(HttpContext ctx)
{
try { await _next(ctx); }
catch (NotFoundException ex)
{
ctx.Response.StatusCode = 404;
await ctx.Response.WriteAsJsonAsync(new { error = ex.Message });
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled exception");
ctx.Response.StatusCode = 500;
await ctx.Response.WriteAsJsonAsync(new { error = "Internal server error" });
}
}
}Perisian Tengah Pengelogan Permintaan
Perisian tengah pengelogan permintaan dan respons berstruktur merekodkan kaedah, laluan, kod status, dan masa berlalu bagi setiap permintaan.
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestLoggingMiddleware> _log;
public RequestLoggingMiddleware(RequestDelegate n, ILogger<RequestLoggingMiddleware> l)
{ _next = n; _log = l; }
public async Task InvokeAsync(HttpContext ctx)
{
var sw = System.Diagnostics.Stopwatch.StartNew();
await _next(ctx);
sw.Stop();
_log.LogInformation(
"{Method} {Path} -> {Status} in {Ms}ms",
ctx.Request.Method,
ctx.Request.Path,
ctx.Response.StatusCode,
sw.ElapsedMilliseconds);
}
}Perisian Tengah Bersyarat dengan UseWhen
UseWhen mencabangkan saluran paip secara bersyarat berdasarkan predikat, tanpa memisahkannya secara kekal. Cabang itu bergabung semula dengan saluran paip utama selepas selesai.
// Apply authentication middleware only to /api/* routes
app.UseWhen(
ctx => ctx.Request.Path.StartsWithSegments("/api"),
apiApp =>
{
apiApp.UseAuthentication();
apiApp.UseAuthorization();
});
// Public routes (/public/*) bypass authentication
app.MapGet("/public/health", () => "OK");
app.MapGet("/api/data", [Authorize] async (DataService s) => await s.GetAsync());Perisian Tengah Pencaching Respons
Perisian tengah pencaching respons terbina dalam menyimpan respons penuh dalam memori. Konfigurasikan dasar cache bagi setiap titik akhir menggunakan pengepala atau atribut.
builder.Services.AddResponseCaching();
app.UseResponseCaching();
app.MapGet("/products", async (AppDbContext db) =>
{
var products = await db.Products.AsNoTracking().ToListAsync();
return Results.Ok(products);
})
.CacheOutput(p => p.Expire(TimeSpan.FromMinutes(2)).Tag("products"));Dunia Sebenar: Perisian Tengah Mod Penyelenggaraan
Perisian tengah mod penyelenggaraan yang membaca bendera daripada konfigurasi, dengan sokongan pemuatan semula panas melalui IOptionsMonitor, dan menolak permintaan yang bukan pemeriksaan kesihatan semasa penyelenggaraan.
public class MaintenanceMiddleware
{
private readonly RequestDelegate _next;
private readonly IOptionsMonitor<MaintenanceOptions> _options;
public MaintenanceMiddleware(RequestDelegate next,
IOptionsMonitor<MaintenanceOptions> opts)
{ _next = next; _options = opts; }
public async Task InvokeAsync(HttpContext ctx)
{
if (_options.CurrentValue.IsEnabled
&& !ctx.Request.Path.StartsWithSegments("/health"))
{
ctx.Response.StatusCode = 503;
ctx.Response.Headers.Append("Retry-After", "300");
await ctx.Response.WriteAsJsonAsync(
new { message = "Service under maintenance" });
return;
}
await _next(ctx);
}
}Semakan Pantas
Mengapakah anda patut melaksanakan IMiddleware dan bukannya pendekatan berasaskan konvensyen apabila anda memerlukan perkhidmatan berskop, seperti DbContext?
Imbas Kembali: Menulis Perisian Tengah Tersuai
Kesimpulan utama:
- Sebaris, menggunakan wakil Use: pantas untuk baris tunggal; berasaskan kelas: boleh diguna semula dan boleh diuji
- Kelas konvensional: pembina menerima RequestDelegate; InvokeAsync(HttpContext)
- IMiddleware: penyelesaian DI bagi setiap permintaan — diperlukan untuk kebergantungan Scoped
- UseWhen: pencabangan bersyarat yang bergabung semula dengan saluran paip utama
- Tulis perisian tengah pengendalian pengecualian terlebih dahulu, iaitu paling luar, untuk menangkap semua ralat
- Cipta kaedah sambungan, UseXxx, untuk pendaftaran yang kemas dan mudah ditemui
Pelajari C# dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 93
- Pelajaran
- 346
Soalan Lazim
Adakah pelajaran “Menulis Perisian Tengah Tersuai” percuma?
Ya — teks penuh “Menulis Perisian Tengah Tersuai” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Akademi C#, tingkat taraf kepada CoddyKit PRO. Kursus Akademi C# merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Menulis Perisian Tengah Tersuai”?
Cipta perisian tengah sebaris dengan Use/Run/Map dan perisian tengah berasaskan kelas dengan InvokeAsync untuk komponen yang boleh digunakan semula. Anda berlatih Akademi C# menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Akademi C#?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Akademi C# di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.
Berapa lamakah pelajaran “Menulis Perisian Tengah Tersuai” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Akademi C# ini?
Ya. Setiap pelajaran Akademi C# menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Gambaran Keseluruhan Saluran Paip ASP.NET Core
- Menulis Perisian Tengah Tersuai
- Pintas Pendek & Percabangan
- Susunan Perisian Tengah & Perisian Tengah Terbina Dalam