AustinHarris.JsonRpc 2.0.1

dotnet add package AustinHarris.JsonRpc --version 2.0.1
                    
NuGet\Install-Package AustinHarris.JsonRpc -Version 2.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AustinHarris.JsonRpc" Version="2.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AustinHarris.JsonRpc" Version="2.0.1" />
                    
Directory.Packages.props
<PackageReference Include="AustinHarris.JsonRpc" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AustinHarris.JsonRpc --version 2.0.1
                    
#r "nuget: AustinHarris.JsonRpc, 2.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AustinHarris.JsonRpc@2.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AustinHarris.JsonRpc&version=2.0.1
                    
Install as a Cake Addin
#tool nuget:?package=AustinHarris.JsonRpc&version=2.0.1
                    
Install as a Cake Tool

AustinHarris.JsonRpc

AustinHarris.JsonRpc is a JSON-RPC 2.0 server library for .NET. Give it a UTF-8 request document and receive the response document: bytes in, bytes out. It handles parsing, method dispatch, parameter binding, batches and error responses. You supply the transport.

The core has no JSON library dependency. Its built-in serializer works on its own; companion packages add Json.NET, System.Text.Json or ASP.NET Core hosting. The built-in tokenizer is a port of jsmn by Serge A. Zaitsev (MIT); the notice ships in the package as THIRD-PARTY-NOTICES.txt.

Targets netstandard2.0, netstandard2.1, net8.0 and net10.0. This is a server library, with no client proxies or server-to-client calls.

Install

dotnet add package AustinHarris.JsonRpc

Coming from 1.x? Read What is new in 2.0 and Upgrading from 1.x first.

Getting started

Declare a service

Save this as server.cs, a .NET 10 file-based app: one C# file with no project file. The #:sdk and #:package directives select the web SDK and package. ServiceBinder.BindMethod registers lambdas served by Kestrel at /rpc.

#:sdk Microsoft.NET.Sdk.Web
#:package AustinHarris.JsonRpc.AspNetCore@2.0.1

using AustinHarris.JsonRpc;
using AustinHarris.JsonRpc.AspNetCore;

ServiceBinder.BindMethod("add", (double l, double r) => l + r);
ServiceBinder.BindMethod("greet", (string who) => "hello " + who);

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddJsonRpc();

var app = builder.Build();
app.MapJsonRpc("/rpc");
app.Run();

Run dotnet run server.cs; Kestrel prints its listening URL. Use dotnet run server.cs -- --urls http://127.0.0.1:5077 to pin it for this request from another terminal:

curl -s -X POST http://127.0.0.1:5077/rpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"add","params":[1,2],"id":1}'
{"jsonrpc":"2.0","result":3.0,"id":1}

On .NET 8, use the same code in Program.cs in an ordinary ASP.NET Core project, install with dotnet add package AustinHarris.JsonRpc.AspNetCore, and drop the two #: lines.

For a service class, create CalculatorService.cs. Derive from JsonRpcService and mark exposed methods with [JsonRpcMethod]. Constructing the service registers its methods in the default session.

using AustinHarris.JsonRpc;

public class CalculatorService : JsonRpcService
{
    [JsonRpcMethod]                 // exposed as "add"
    private double add(double l, double r) => l + r;

    [JsonRpcMethod("multiply")]     // exposed under an explicit name
    public int Multiply(int l, int r) => l * r;

    [JsonRpcMethod]
    public string StringMe(string x) => x;
}

Methods can be private. Parameters can be positional or named. Optional parameter defaults are honoured; [JsonRpcParam("name")] overrides a parameter's JSON name. Keep the service instance alive; it serves concurrent requests, so its state must be thread-safe.

Both examples use the default session (Handler.DefaultSessionId()). Lambdas and classes can be mixed in one session when their method names differ; both examples register add, so keep one of them. The next step drives CalculatorService in process, without a transport.

A method is a callable identified by the method member of a request; its implementation is a delegate, a [JsonRpcMethod] member of a class, or a member of a bound interface.

Process requests

Put this code in Program.cs in a console project targeting net8.0 or net10.0. It calls the service through both string overloads and the byte entry point. The string overloads transcode into the byte pipeline.

using System;
using System.Buffers;
using System.Text;
using AustinHarris.JsonRpc;

var service = new CalculatorService();   // binds itself to the default session; keep a reference

// Strings, asynchronous invocation.
string response = await JsonRpcProcessor.ProcessAsync("""{"jsonrpc":"2.0","method":"add","params":[1,2],"id":1}""");
// {"jsonrpc":"2.0","result":3.0,"id":1}

// Strings, synchronous, on the calling thread. Named parameters.
string sync = JsonRpcProcessor.ProcessSync("""{"method":"multiply","params":{"l":6,"r":7},"id":2}""");
// {"jsonrpc":"2.0","result":42,"id":2}

// Bytes: the native path. The string overloads transcode into it.
var output = new ArrayBufferWriter<byte>();
JsonRpcProcessor.Process(Handler.DefaultSessionId(), """{"method":"add","params":[2,3],"id":3}"""u8, output);
Console.WriteLine(Encoding.UTF8.GetString(output.WrittenSpan));   // nothing is written for a notification

The string responses appear in the comments above. The byte call prints:

{"jsonrpc":"2.0","result":5.0,"id":3}

A batch returns an array when it contains calls that need responses. A notification has no id and produces no response. A """..."""u8 literal is a ReadOnlySpan<byte> (C# 11 and later). A bare byte[] is ambiguous between the memory and span overloads on C# 12 and 13; pass it as AsSpan() there.

Use JsonRpcProcessor.ProcessAsync for methods returning Task or ValueTask. The synchronous entry points do not await those methods.

Performance

These results compare 1.2.3 and 2.0 with the same five requests on the same machine in one benchmark job. The 2.0 runs used the built-in serializer on a Hugging Face Jobs cpu-performance host (AMD EPYC 7R13, 32 cores) with .NET 10, Release and Server GC. Each range is the low and high over the job's runs; the ratios are of the medians.

JSON-RPC.Net 1.2.3 and 2.0 throughput through the string and byte entry points

Path RPC/s Against 1.2.3
1.2.3, Task<string> Process(string), thread pool, best batch size 1.29 M to 2.41 M
2.0, the same string API and the same loop 9.83 M to 11.1 M 6.0×
2.0, Process(bytes), 32 dedicated threads 44.2 M to 45.7 M 24.3×
2.0, ProcessAsync(bytes), 32 awaited workers 36.3 M to 40.5 M 20.7×

These measurements cover the library without a transport. The asynchronous byte row uses methods that complete inline. For Kestrel TCP with 256 requests in flight per connection and EnableAsyncMethods = false, the measured figure is 18.5 M RPC/s on loopback, with clients and server on the same machine.

See the benchmark tables for conditions and the benchmark explorer for the data.

Companion packages

Install only the integrations your host needs. Use matching package versions.

Upgrading from 1.x

Most service methods can stay as they are. Review these changes before switching:

  • Json.NET is now a companion package. Use it for JsonSerializerSettings and settings-based compatibility helpers; JsonRequest.Params follows the selected serializer's object model.
  • Review string overloads, especially calls with a positional null context. Name the context argument explicitly; serializer-taking overloads have changed.
  • Check client-visible behaviour: notifications never return responses, responding batches stay arrays, and version values, named parameters and conversion failures are validated.
  • Unhandled exceptions now return internal errors with exception details hidden by default.

Upgrading from 1.x covers every API and wire change, and What is new in 2.0 is the full changelog.

Documentation

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 was computed.  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 is compatible.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on AustinHarris.JsonRpc:

Package Downloads
Casper.Net.Sdk

C# SDK For the Casper Network

AustinHarris.JsonRpc.SystemTextJson

System.Text.Json serializer for AustinHarris.JsonRpc. Reads UTF-8 parameters and writes results directly to the response buffer, configured with JsonSerializerOptions.

AustinHarris.JsonRpc.Newtonsoft

Json.NET serializer for AustinHarris.JsonRpc. Uses JsonSerializerSettings for converters, contract resolvers and lenient JSON input.

AustinHarris.JsonRpc.AspNetCore

ASP.NET Core hosting for AustinHarris.JsonRpc. Adds HTTP endpoints and raw Kestrel connections over TCP, Unix sockets and named pipes, with dependency injection.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on AustinHarris.JsonRpc:

Repository Stars
bonesoul/CoiniumServ
Next-gen crypto currency mining pool software
Version Downloads Last Updated
2.0.1 194 9/28/2026
2.0.0 169 9/28/2026
2.0.0-preview.3 73 9/28/2026
2.0.0-preview.2 66 9/28/2026
2.0.0-preview.1 66 9/25/2026
1.2.3 59,151 9/11/2021
1.2.2 31,384 5/22/2020
1.2.2-ci-112095285-8 631 5/22/2020
1.2.1.2 852 5/22/2020
1.2.1.2-ci-111992021-7 614 5/22/2020
1.2.0.1 1,932 5/1/2020
1.2.0.1-ci-92709240-5 667 5/1/2020
1.2.0.1-ci-92708299-4 654 5/1/2020
1.2.0.1-ci-92695812-2 638 5/1/2020
1.2.0.1-ci-92679453-22 658 5/1/2020
1.2.0.1-ci-111987561-6 617 5/22/2020
1.1.70 58,332 7/31/2017
1.1.63 90,032 11/6/2016
1.1.62 1,647 11/6/2016
1.0.4.52 33,770 11/6/2016
Loading failed

2.0.1: adds the jsmn copyright and permission notice (THIRD-PARTY-NOTICES.txt) to the package; no code change. 2.0.0: the request pipeline is built around UTF-8 bytes (ReadOnlySequence, ReadOnlyMemory or ReadOnlySpan in, IBufferWriter out), the JSON serializer is pluggable with the built-in serializer as the default and Json.NET and System.Text.Json as packages, and Task and ValueTask methods are supported again through ProcessAsync with cooperative cancellation. Document and batch limits are on by default (JsonRpcLimits), reserved method names are refused at registration, unknown named parameters are rejected, an error handler receives the exception the method threw, and the four assemblies are strong-named with one key that stays fixed from here on. Six times the throughput of 1.2.3 through the 1.x string API and twenty-four times through the byte entry points, measured on a 32-core Hugging Face Jobs host (see the README). InProcessClient is removed; three legacy members are obsolete at warning level with diagnostic ids JSONRPC0001 to JSONRPC0003. What is new: https://astn.github.io/JSON-RPC.NET/changelog.html. Upgrading from 1.x: https://astn.github.io/JSON-RPC.NET/upgrading.html