Http-Server-Handler
Diese Seite wurde automatisch aus dem Englischen übersetzt. Original lesen
In Sisk Version 0.16 haben wir die Klasse HttpServerHandler eingeführt, die das übergeordnete Verhalten von Sisk erweitern und zusätzliche Ereignis‑Handler bereitstellen soll, wie z. B. die Behandlung von Http‑Anfragen, Routern, Kontext‑Bags und mehr.
Die Klasse bündelt Ereignisse, die während der Lebensdauer des gesamten HTTP‑Servers und auch einer Anfrage auftreten. Das Http‑Protokoll verfügt nicht über Sitzungen, sodass es nicht möglich ist, Informationen von einer Anfrage zur nächsten zu erhalten. Sisk bietet derzeit eine Möglichkeit, Sitzungen, Kontexte, Datenbankverbindungen und andere nützliche Provider zu implementieren, um Ihre Arbeit zu unterstützen.
Bitte lesen Sie diese Seite, um zu erfahren, wann jedes Ereignis ausgelöst wird und welchen Zweck es hat. Sie können auch den Lebenszyklus einer HTTP‑Anfrage ansehen, um zu verstehen, was bei einer Anfrage passiert und wo Ereignisse ausgelöst werden. Der HTTP‑Server ermöglicht die gleichzeitige Verwendung mehrerer Handler. Jeder Ereignisaufruf ist synchron, das heißt, er blockiert den aktuellen Thread für jede Anfrage oder jeden Kontext, bis alle mit dieser Funktion verbundenen Handler ausgeführt und abgeschlossen sind.
Im Gegensatz zu RequestHandlers können sie nicht auf bestimmte Routen‑Gruppen oder einzelne Routen angewendet werden. Stattdessen gelten sie für den gesamten HTTP‑Server. Sie können Bedingungen innerhalb Ihres Http‑Server‑Handlers festlegen. Darüber hinaus wird für jede Sisk‑Anwendung ein Singleton jedes HttpServerHandler definiert, sodass nur eine Instanz pro HttpServerHandler existiert.
Ein praktisches Beispiel für die Verwendung von HttpServerHandler ist das automatische Freigeben einer Datenbankverbindung am Ende einer Anfrage.
// DatabaseConnectionHandler.cs
public class DatabaseConnectionHandler : HttpServerHandler
{
protected override void OnHttpRequestClose(HttpServerExecutionResult result)
{
var requestBag = result.Request.Context.RequestBag;
// prüft, ob die Anfrage einen DbContext definiert hat
// in seinem Kontext‑Bag
if (requestBag.IsSet<DbContext>())
{
var db = requestBag.Get<DbContext>();
db.Dispose();
}
}
}
public static class DatabaseConnectionHandlerExtensions
{
public static DbContext GetDbContext(this HttpRequest request)
{
return request.Bag.GetOrAdd(() => new DbContext());
}
}Mit dem obigen Code ermöglicht die GetDbContext‑Erweiterung, einen Verbindungs‑Kontext direkt aus dem HttpRequest‑Objekt zu erstellen. Eine nicht freigegebene Verbindung kann beim Arbeiten mit der Datenbank Probleme verursachen, daher wird sie in OnHttpRequestClose beendet.
Sie können einen Handler auf einem Http‑Server in Ihrem Builder oder direkt mit HttpServer.RegisterHandler registrieren.
// Program.cs
class Program
{
static void Main(string[] args)
{
using var app = HttpServer.CreateBuilder()
.UseHandler<DatabaseConnectionHandler>()
.Build();
app.Router.MapInstance(new UserController());
app.Start();
}
}Damit kann die Klasse UsersController den Datenbank‑Kontext wie folgt nutzen:
// UserController.cs
[RoutePrefix("/users")]
public class UserController : ApiController
{
[RouteGet()]
public async Task<HttpResponse> List(HttpRequest request)
{
var db = request.GetDbContext();
var users = db.Users.ToArray();
return JsonOk(users);
}
[RouteGet("<id>")]
public async Task<HttpResponse> View(HttpRequest request)
{
var db = request.GetDbContext();
int userId = request.RouteParameters["id"].GetInteger();
var user = db.Users.FirstOrDefault(u => u.Id == userId);
return JsonOk(user);
}
[RoutePost]
public async Task<HttpResponse> Create(HttpRequest request)
{
var db = request.GetDbContext();
var user = await request.GetJsonContentAsync<User>();
ArgumentNullException.ThrowIfNull(user);
db.Users.Add(user);
await db.SaveChangesAsync();
return JsonMessage("User added.");
}
}Der obige Code verwendet Methoden wie JsonOk und JsonMessage, die in ApiController eingebaut sind und von einem RouterController erben:
// ApiController.cs
public class ApiController : RouterModule
{
public HttpResponse JsonOk(object value)
{
return new HttpResponse(200)
.WithContent(JsonContent.Create(value, null, new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true
}));
}
public HttpResponse JsonMessage(string message, int statusCode = 200)
{
return new HttpResponse(statusCode)
.WithContent(JsonContent.Create(new
{
Message = message
}));
}
}Von Handlern ausgelöste Ausnahmen #
Seit Sisk 1.7 werden von Server‑Handlern ausgelöste Ausnahmen wie folgt behandelt:
- Ausnahmen, die in
OnServerStarting,OnServerStartedundOnSetupRouterausgelöst werden, stoppen den Serverstart. Sie werden in eineInvalidOperationExceptiongewrappt, wobei die ursprüngliche Ausnahme inInnerExceptionenthalten ist. - Ausnahmen, die in anderen Ereignissen ausgelöst werden, werden in ErrorsLogsStream geschrieben und die übrigen Handler werden weiterhin aufgerufen, es sei denn, ThrowExceptions ist aktiviert. Ist
ThrowExceptionsaktiviert, werden sie in eineInvalidOperationExceptiongewrappt. - Ausnahmen, die in
OnHttpRequestCloseundOnExceptionoder beim Formatieren der Zugriffs‑ und Fehlerprotokolle ausgelöst werden, entkommen niemals der HTTP‑Engine, selbst wennThrowExceptionsaktiviert ist. Sie werden inErrorsLogsStreamgeschrieben. In früheren Versionen konnten sie den Prozess beenden oder die Verbindung offen lassen.
Entwickler können mit dieser Klasse Sitzungen, Kontexte und Datenbankverbindungen implementieren. Der bereitgestellte Code zeigt ein praktisches Beispiel mit dem DatabaseConnectionHandler, das die Freigabe von Datenbankverbindungen am Ende jeder Anfrage automatisiert.
Die Integration ist unkompliziert, da Handler während der Server‑Einrichtung registriert werden. Die Klasse HttpServerHandler bietet ein leistungsfähiges Werkzeugset zur Ressourcenverwaltung und zur Erweiterung des Sisk‑Verhaltens in HTTP‑Anwendungen.