Middleware
EmbedIO
nuget add Kinetq.LiquidPages.EmbedIO
var liquidWebModule = new LiquidWebModule("/")
{
LiquidResponseMiddleware = _liquidResponseMiddleware,
ExcludedPaths = new Regex[]
{
new Regex("^/api/.*"),
new Regex("^/static/.*")
}
};
webServer.WithModule(liquidWebModule);
Custom Middleware
Otherwise if there is no existing middleware for your webserver, the implementation would still be simple and look something like this:
try
{
var liquidRequest = new LiquidRequestModel()
{
Route = request.Url.AbsolutePath,
QueryParams = request.Url.Query.GetQueryParams(),
Headers = request.Headers
};
if (request.HasEntityBody)
{
using var reader = new StreamReader(request.InputStream, Encoding.UTF8);
liquidRequest.Body = await reader.ReadToEndAsync();
}
var responseModel =
await LiquidResponseMiddleware.HandleRequestAsync(liquidRequest);
response.ContentLength64 = responseModel.Content.Length;
response.ContentType = responseModel.ContentType;
response.StatusCode = responseModel.StatusCode;
await response.OutputStream.WriteAsync(responseModel.Content);
}
catch (Exception ex)
{
response.StatusCode = 500;
byte[] errorBuffer = Encoding.UTF8.GetBytes($"Internal Server Error: {ex.Message}");
response.ContentLength64 = errorBuffer.Length;
response.ContentType = "text/html";
await response.OutputStream.WriteAsync(errorBuffer);
}
finally
{
response.Close();
}
}
Liquid Response Middleware
The ILiquidResponseMiddleware is the engine that ties everything together. After injecting it into your application, you call HandleRequestAsync with a LiquidRequestModel that encapsulates the incoming request. The middleware then orchestrates route matching, data retrieval, template parsing, and response generation, returning a LiquidResponseModel ready to be written to the output stream.
ILiquidResponseMiddlewareis the core service; itsHandleRequestAsyncmethod accepts aLiquidRequestModelcontaining the route, query parameters, body, and headers.The middleware iterates through all registered routes, matching the request path against each
RoutePattern(regex).When a match is found, it optionally invokes the route’s
Executedelegate to obtain a view model.The middleware then parses the Liquid template using the Fluid engine, passing the view model (accessible as
view_model) and any custom filters registered in the system.If no route matches, it attempts to serve static files (e.g., CSS, images) from the default file provider.
If neither a route nor a static file is found, it falls back to any configured error routes (such as the 404 route described above) to produce an appropriate response.
The final output is a byte array with the correct MIME type and HTTP status code, packaged in a
LiquidResponseModel.This design makes the middleware adaptable to any web server, as demonstrated in the generic integration example at the beginning of this document. For a detailed look at the implementation, see the
LiquidResponseMiddleware.csfile in the repository.
