WebHost 9.3.0
dotnet add package WebHost --version 9.3.0
NuGet\Install-Package WebHost -Version 9.3.0
<PackageReference Include="WebHost" Version="9.3.0" />
<PackageVersion Include="WebHost" Version="9.3.0" />
<PackageReference Include="WebHost" />
paket add WebHost --version 9.3.0
#r "nuget: WebHost, 9.3.0"
#:package WebHost@9.3.0
#addin nuget:?package=WebHost&version=9.3.0
#tool nuget:?package=WebHost&version=9.3.0
WebHost
WebHost is an ultra-lightweight web server framework for .NET, designed to handle HTTP, WebSocket, and secure TLS/mTLS communication. It provides a modular and extensible architecture, integrating seamlessly with .NET's IHost
for dependency injection and middleware configuration.
Purpose
Provide fully customizable and low level access to http request. This package was born from the need to run a .NET C# web server on any .NET supported platform, which is not possible using ASP.NET Core.
Fully Native
No third party libraries used, the only dependencies are
Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
Microsoft.Extensions.Hosting (>= 9.0.0)
Features
- Flexible Hosting: Supports both TLS and non-TLS connections.
- WebSocket Support: Implements WebSocket communication in compliance with RFC 6455.
- Middleware Pipeline: Fully configurable request handling pipeline.
- Route Mapping: Dynamically registers route handlers with attributes or fluent API.
- Extensible Architecture: Integrates with .NET's dependency injection for custom services and middleware.
- Lightweight Design: Minimal overhead with high-performance socket-based networking.
HTTP Version support
- HTTP/1.x: Yes
- HTTP/2.0: In progress
- HTTP/3.0: Not planned yet
Resource Hosting (Static pages)
- Yes
Websockets
- RFC 6455 protocol
- Missing fragmented frames support (to be added)
Getting Started
Prerequisites
- .NET SDK (version 8.0 or later recommended)
Installation
Clone the repository and navigate to the project directory:
git clone <repository-url>
cd WebHost
Examples
Refer to Examples folder for detailed usage examples!
Usage
Create and Configure a WebHost
var host = WebHostApp.CreateBuilder()
.SetEndpoint("127.0.0.1", 9001)
.UseTls(options =>
{
options.ServerCertificate = LoadCertificate();
})
.MapGet("/route", sp => async context =>
{
// Access http request params
//
Console.WriteLine($"Received HttpMethod: {context.Request.HttpMethod}");
Console.WriteLine($"Received query params: {context.Request.QueryParameters}");
foreach (var header in context.Request.Headers)
Console.WriteLine($"Received header: {header}");
Console.WriteLine($"Received body: {context.Request.Body}");
// Respond
//
var exampleClass = new
{
Name = "John",
Address = "World"
};
var jsonString = JsonSerializer.Serialize(exampleClass);
context.Response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(jsonString, Encoding.UTF8, "application/json"),
};
context.Response.Headers.ConnectionClose = false;
context.Response.Content.Headers.ContentLength = Encoding.UTF8.GetByteCount(jsonString);
await context.SendAsync(await context.Response.ToBytes());
})
.Build();
await host.RunAsync();
static X509Certificate2 LoadCertificate() {
// Load your TLS certificate here
}
Middleware Example - Global Error Handling
// Basic global error handling middleware example
//
builder.UseMiddleware(scope => async (context, next) =>
{
var logger = scope.GetRequiredService<ILogger<Program>>();
logger.LogDebug("Executing..");
// Wrap the endpoint in a try catch for global error handling
//
try
{
await next(context);
}
// In case a ServiceException type was caught, the status code is known to be used on the http response
//
catch (ServiceException serviceEx)
{
logger.LogError("ServiceException was caught and being handled:{Message}", serviceEx.Message);
var message = serviceEx.Message;
context.Response = new HttpResponseMessage((HttpStatusCode)serviceEx.StatusCode)
{
Content = new StringContent(message, Encoding.UTF8, "text/pain"),
};
context.Response.Headers.ConnectionClose = false;
context.Response.Content.Headers.ContentLength = Encoding.UTF8.GetByteCount(message);
await context.SendAsync(await context.Response.ToBytes());
}
// In case a regular exception is caught, assume the http response status code to be 500
//
catch (Exception ex)
{
logger.LogError("Exception was caught and being handled:{Message}", ex.Message);
var message = ex.Message;
context.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(message, Encoding.UTF8, "text/pain"),
};
context.Response.Headers.ConnectionClose = false;
context.Response.Content.Headers.ContentLength = Encoding.UTF8.GetByteCount(message);
await context.SendAsync(await context.Response.ToBytes());
}
});
WebSocket Example
.MapGet("/websocket", scope => async (context) =>
{
var arrayPool = ArrayPool<byte>.Shared;
var buffer = arrayPool.Rent(10000000);
while (true)
{
var receivedData = await context.WsReadAsync(buffer);
if (receivedData.Item2 == WsFrameType.Close)
break;
if (receivedData.Item1.IsEmpty)
break;
await context.WsSendAsync(receivedData.Item1, 0x01);
}
arrayPool.Return(buffer);
});
Architecture
Core Components
WebHostApp
- The main entry point for configuring and starting the server.
- Supports fluent API for configuration.
WebHostBuilder
- Provides methods to configure endpoints, TLS settings, and middleware.
Middleware Pipeline
- Processes requests through a dynamic pipeline of middleware components.
WebSocket and TLS Support
- Handles WebSocket handshakes and messages.
- Manages secure communication with TLS/mTLS.
Contributing
Contributions are welcome! Feel free to open issues or submit pull requests to improve the project.
License
This project is licensed under the MIT License. See the LICENSE
file for details.
Acknowledgements
- Built with .NET and inspired by high-performance web hosting frameworks.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Hosting (>= 9.0.0)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Hosting (>= 9.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.