CoAP.NET is a modernized CoAP framework for .NET 10. It keeps the original CoAP.NET client and server model, blockwise transfer, observe support, and resource tree, while adding Microsoft.Extensions.Logging integration, Native AOT analyzer compatibility, and optional DTLS PSK transport.
See ROADMAP.md for the CoAP route adapter and low-allocation plan. The Resource/MVC sample and migration guide are available in CoAP.Example/CoAP.ResourceMvc and docs/resource-mvc-migration.md. C12 release validation is tracked in docs/c12-release-checklist.md.
dotnet add package <coap-package-id> --version 3.0.0- CoAP client APIs for GET, POST, PUT, DELETE, discovery, and observe.
- CoAP server APIs with resource routing and blockwise support.
- UDP transport for
coap://and DTLS PSK transport forcoaps://. - Host-integrated startup through
AddCoapServer(),AddCoapResources(),AddCoapMvc(), andMapCoapResources(). - Endpoint filters, authorization hooks, and request context hooks for host-owned policy integration.
- Logging through
Microsoft.Extensions.Logging. - Packable as an independent NuGet package.
Resource, IResource, ResourceAttributes, DiscoveryResource, resource
tree, and .well-known/core remain CoAP/CoRE protocol concepts inside
CoAP.NET. They are not host application domain objects. Existing Resource-style
applications can continue to add resources to CoapServer, while newer host
integration should use Resource-oriented hosting APIs such as
AddCoapServer(), AddCoapResources(), and MapCoapResources().
The current compatibility entry points are:
AddCoapServer(),AddCoapResources()/AddCoapMvc(), andMapCoapResources()for host-managed server lifetime and resource endpoint mapping.CoAP.Server.CoapServerfor server lifetime, endpoint registration, and the root resource tree.CoAP.Server.Resources.Resource/IResourcefor protocol resources, method handlers, attributes, observe, and discovery.CoAP.CoapClientandCoAP.Requestfor synchronous and asynchronous client requests, observe, and discovery.CoAP.Channel.DtlsPskChannelandDtlsPskClientChannelfor optional DTLS PSK transport.CoAP.Server.Routing.CoapRouteEndpointfor low-level route handler compatibility. It is useful for tests and adapters, but it is not the recommended future host application API.
CoAP.NET no longer ships a custom CoAP.Log abstraction. Configure the shared
logger factory once during application startup:
using CoAP;
CoapLogging.LoggerFactory = loggerFactory;The default logger factory is NullLoggerFactory.Instance, so libraries can use
CoAP.NET without configuring logging.
using CoAP;
var client = new CoapClient(new Uri("coap://127.0.0.1:5683/db/demo/m/cpu?token=secret"))
{
Timeout = 5000,
};
Response response = client.Post("cpu,host=a value=1 1", MediaType.TextPlain);For DTLS PSK, create an explicit endpoint and assign it to the client:
using CoAP;
using CoAP.Channel;
using CoAP.Net;
var config = new CoapConfig();
using var endpoint = new CoAPEndPoint(
new DtlsPskClientChannel("device-1", "shared-secret"),
config);
endpoint.Start();
var client = new CoapClient(new Uri("coaps://127.0.0.1:5684/db/demo/m/cpu?token=secret"), config)
{
EndPoint = endpoint,
Timeout = 10000,
};
Response response = client.Post("cpu,host=a value=1 1", MediaType.TextPlain);Recommended host-managed startup:
builder.Services.AddCoapServer(options =>
{
options.ListenAnyIP(5683);
});
builder.Services.AddCoapResources();
var app = builder.Build();
app.MapCoapResources();
app.Run();Native AOT hosts should register generated endpoint factories and source-generated JSON metadata:
builder.Services.AddCoapJsonPayloadBinder(MyCoapJsonContext.Default);
builder.Services.AddCoapResources(options =>
{
options.AddEndpointFactory(MyGeneratedCoapEndpoints.Create);
});Reflection-based resource discovery remains available for non-AOT hosts or compatibility tests:
builder.Services.AddCoapResources(options =>
{
options.AddReflectionResourceDiscovery();
});Resource attribute routing:
using CoAP;
using CoAP.Server.Routing;
using System.Threading;
using System.Threading.Tasks;
[CoapResource]
[CoapRoute("sensors/{sensor}")]
public sealed class SensorCoapResource : CoapResourceBase
{
[CoapPost("readings")]
[CoapResourceTitle("Sensor reading upload")]
public ValueTask<CoapRouteResult> UploadReadingAsync(
string sensor,
CancellationToken cancellationToken)
{
var payload = Payload;
return new ValueTask<CoapRouteResult>(CoapRouteResult.Changed());
}
}Filters and host-owned security hooks:
using CoAP;
using CoAP.Server.Routing;
[CoapResource]
[CoapRoute("diagnostics/{target}")]
public sealed class DiagnosticsCoapResource
{
[CoapGet("status")]
[CoapAuthorize("diagnostics.read")]
public CoapRouteResult Status(CoapRouteContext context)
{
var tenant = (string)context.Items["tenant"];
return CoapRouteResult.Text(StatusCode.Content, tenant);
}
}Hosts register ICoapRequestContextHook, ICoapAuthorizationHook, and
ICoapEndpointFilter implementations in DI; they are resolved from the request
scope when available. CoAP.NET only defines metadata, ordering, and invocation
contracts; tenant isolation, identity checks, audit, and human confirmation
remain host application responsibilities.
Legacy Resource tree compatibility:
using CoAP.Server;
using CoAP.Server.Resources;
var server = new CoapServer();
server.Add(new HelloResource());
server.Start();
sealed class HelloResource : Resource
{
public HelloResource()
: base("hello")
{
}
protected override void DoGet(CoapExchange exchange)
{
exchange.Respond("Hello from CoAP.NET");
}
}The full Resource-style server sample is in
CoAP.Example/CoAP.Server. It registers resources such as hello, storage,
large, separate, and time by calling server.Add(new ...Resource(...)).
The full host-managed Resource/MVC sample is in
CoAP.Example/CoAP.ResourceMvc. It demonstrates AddCoapServer(),
AddCoapResources(), MapCoapResources(), JSON DTO binding, binary payloads,
query and option binding, Content-Format / Accept negotiation, Observe
metadata, generated .well-known/core output, and stable error responses.
Low-level route endpoint compatibility:
using CoAP;
using CoAP.Server;
using CoAP.Server.Routing;
using System.Linq;
using System.Threading.Tasks;
var server = new CoapServer();
var routes = CoapRouteEndpoint.Create(new[]
{
CoapRoute.Post(
"diagnostics/{target}/ping",
() => new DiagnosticsCoapResource(),
resource => resource.PingAsync())
});
server.Add(routes.ToArray());
server.Start();
sealed class DiagnosticsCoapResource : CoapResourceBase
{
public ValueTask<CoapRouteResult> PingAsync()
{
var target = RouteValues["target"];
var bytes = Payload;
var payload = System.Text.Encoding.UTF8.GetBytes("{\"ok\":true}");
return new ValueTask<CoapRouteResult>(
CoapRouteResult.Content(payload, MediaType.ApplicationJson)
.WithMaxAge(30)
.WithETag(new byte[] { 0x01, 0x02 })
.WithLocationPath($"diagnostics/{target}/ping"));
}
}DTLS PSK server endpoint:
using CoAP;
using CoAP.Channel;
using CoAP.Net;
using CoAP.Server;
var config = new CoapConfig();
var server = new CoapServer(config);
var keys = new Dictionary<string, string>
{
["device-1"] = "shared-secret",
};
server.AddEndPoint(new CoAPEndPoint(new DtlsPskChannel(5684, keys), config));
server.Start();dotnet pack CoAP.NET/CoAP.NET.csproj -c ReleaseThe package is written to CoAP.NET/artifacts by default.
Run these commands from the SonnetDB/extensions/IoTSharp.CoAP.NET directory:
dotnet build CoAP.NET/CoAP.NET.csproj
dotnet build CoAP.Example/CoAP.Server/CoAP.Server.csproj
dotnet build CoAP.Example/CoAP.Client/CoAP.Client.csproj
dotnet test CoAP.Test/CoAP.Test.csprojThe baseline tests cover:
- Resource tree and discovery:
ResourceTreeTest,ResourceAttributesTest,ResourceTest. - Server start/stop and client request flow:
StartStopTest,CoapClientTest. - Blockwise transfer:
BlockwiseTransferTest,RandomAccessBlockTest. - Observe behavior:
CoapClientTest,MemoryLeakingMapTest. - Message and option compatibility:
MessageTypeTest,OptionTest,BlockOptionTest.
DTLS PSK transport is exposed through DtlsPskChannel and
DtlsPskClientChannel; C12 adds automated route + DTLS PSK smoke coverage in
CoapC12SmokeTest.
Run the C12 smoke tests and route benchmark from this directory:
dotnet test CoAP.Test/CoAP.Test.csproj -c Release --filter FullyQualifiedName~CoapC12SmokeTest
dotnet run -c Release --project CoAP.Benchmarks/CoAP.Benchmarks.csproj -- --filter *CoapRouteMatcherBenchmark*The release checklist, trim/AOT warning inventory, and pack verification steps are maintained in docs/c12-release-checklist.md.
This project preserves the original CoAP.NET BSD-style license. See LICENSE for details.
CoAP.NET is based on Californium, a CoAP framework in Java by Matthias Kovatsch, Dominique Im Obersteg, and Daniel Pauli at ETH Zurich.