Anemonis.AspNetCore.JsonRpc

JSON-RPC 2.0 middleware for ASP.NET Core 3 based on the "JSON-RPC 2.0 Transport: HTTP" specification


Keywords
aspnetcore, json-rpc, json, rpc, c-sharp, dotnet, middleware, protocol
License
MIT
Install
Install-Package Anemonis.AspNetCore.JsonRpc -Version 1.18.0-beta-20191129.2

Documentation

Anemonis.AspNetCore.JsonRpc

JSON-RPC 2.0 middleware for ASP.NET Core 3 based on the JSON-RPC 2.0 Transport: HTTP specification and the Anemonis.JsonRpc serializer.

Release Current
Artifacts
Code Health
Build Status

Project Details

  • The middleware transparently handles batch JSON-RPC requests.
  • The middleware automatically handles standard JSON-RPC errors.
  • The middleware does not verify the Content-Length and Accept headers.
  • A service supports default method parameter values for named parameters not provided in a request.

In addition to the standard JSON-RPC error codes the middleware may return the following JSON-RPC errors:

Code Reason
-32000 The provided batch contains requests with duplicate identifiers

In addition to the standard JSON-RPC HTTP error codes the middleware may return the following HTTP error codes:

Code Reason
415 The Content-Encoding header is specified

According to the current logging configuration, the following events may appear in a journal:

ID Level Reason
1100 Debug A JSON-RPC notification handled successfully
1110 Debug A JSON-RPC request handled with result successfully
1111 Debug A JSON-RPC request handled with error successfully
1200 Information A JSON-RPC request handled with result as notification due to client demand
1201 Information A JSON-RPC request handled with error as notification due to client demand
1300 Warning A JSON-RPC notification handled as request due to server configuration
1400 Error The request contains invalid JSON-RPC data
1401 Error A JSON-RPC request is invalid
1402 Error The request contains a JSON-RPC batch with duplicate identifiers

Code Examples

[JsonRpcRoute("/api")]
public class JsonRpcService : IJsonRpcService
{
    [JsonRpcMethod("m1", "p1", "p2")]
    public Task<long> InvokeMethod1Async(long p1, long p2)
    {
        if (p2 == 0L)
        {
            throw new JsonRpcServiceException(100L);
        }

        return Task.FromResult(p1 / p2);
    }

    [JsonRpcMethod("m2", 0, 1)]
    public Task<long> InvokeMethod2Async(long p1, long p2)
    {
        return Task.FromResult(p1 + p2);
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddJsonRpc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseJsonRpc();
    }
}

or

[JsonRpcRoute("/api")]
public class JsonRpcHandler : IJsonRpcHandler
{
    public IReadOnlyDictionary<string, JsonRpcRequestContract> GetContracts()
    {
        var contract1Types = new Dictionary<string, Type>();
        var contract2Types = new Type[2];

        contract1Types["p1"] = typeof(long);
        contract1Types["p2"] = typeof(long);
        contract2Types[0] = typeof(long);
        contract2Types[1] = typeof(long);

        var contracts = new Dictionary<string, JsonRpcRequestContract>();

        contracts["m1"] = new JsonRpcRequestContract(contract1Types);
        contracts["m2"] = new JsonRpcRequestContract(contract2Types);

        return contracts;
    }

    public Task<JsonRpcResponse> HandleAsync(JsonRpcRequest request)
    {
        var response = default(JsonRpcResponse);

        switch (request.Method)
        {
            case "m1":
                {
                    var p1 = (long)request.ParametersByName["p1"];
                    var p2 = (long)request.ParametersByName["p2"];

                    response = p2 != 0L ?
                        new JsonRpcResponse(p1 / p2, request.Id) :
                        new JsonRpcResponse(new JsonRpcError(100L), request.Id);
                }
                break;
            case "m2":
                {
                    var p1 = (long)request.ParametersByPosition[0];
                    var p2 = (long)request.ParametersByPosition[1];

                    response = new JsonRpcResponse(p1 + p2, request.Id);
                }
                break;
        }

        return Task.FromResult(response);
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddJsonRpc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseJsonRpc();
    }
}

Quicklinks