JsonHCS.Net.Proxies 1.6.0

Additional Details

Reverted plugin api change in 1.6.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package JsonHCS.Net.Proxies --version 1.6.0                
NuGet\Install-Package JsonHCS.Net.Proxies -Version 1.6.0                
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="JsonHCS.Net.Proxies" Version="1.6.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add JsonHCS.Net.Proxies --version 1.6.0                
#r "nuget: JsonHCS.Net.Proxies, 1.6.0"                
#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.
// Install JsonHCS.Net.Proxies as a Cake Addin
#addin nuget:?package=JsonHCS.Net.Proxies&version=1.6.0

// Install JsonHCS.Net.Proxies as a Cake Tool
#tool nuget:?package=JsonHCS.Net.Proxies&version=1.6.0                

JsonHCS.Net.Proxies

JsonHCS.Net.Proxies for .Net is a JsonHCS.Net based proxy generator for easy api definitions.

NuGet version (JsonHCS.Net.Proxies)

JsonHCS.Net.Proxies recently got some big updates and should support most basic scenario's now, feel free to suggest new features!

Support

Supported platforms: .Net Standard 1.5+

Supported api definitions:

  • Abstract class
  • Class with virtual/abstract properties
  • Interface

The following attributes are recognised and used for api generation: ASP.NET attributes:

  • RouteAttribute
  • HttpGetAttribute
  • HttpPostAttribute
  • HttpPutAttribute
  • HttpDeleteAttribute
  • FromBodyAttribute
  • FromQueryAttribute
  • FromFormAttribute (TBD)
  • FromHeaderAttribute
  • FromRouteAttribute

JsonHCS specific:

  • RawStringAttribute (Returns an unparsed string, default will try to parse the string as json)

Simple usage

//For the proxy:
using JsonHCSNet.Proxies;

//For the attribute definitions (optional)
//recommended for clients (smaller footprint)
using JsonHCSNet.Proxies.ApiDefinition;

//Or if you want to use the AspNetCore.Mvc.Core nuget
//recommended for asp.net core servers using the library
//using Microsoft.AspNetCore.Mvc;
  • Construct with your preferred options and use it!
var settings = new JsonHCS_Settings()
{
    CookieSupport = true,                   //To support sessions and thus cookies
    AddDefaultAcceptHeaders = true,         //Adds default acceptance headers for json types
    UserAgent = "MyAwesomeSampleAgent"      //Because why not, this is usually ignored anyways
};
JsonHCSProxyGenerator pg = new JsonHCSProxyGenerator(settings);
var client = pg.CreateClassProxy<SampleController>("https://jsonplaceholder.typicode.com/");

//use by just calling the api definition, the library will take care of any conversions/requests
var allPosts = await client.Get();
var onePost = await client.GetPost(2);
await client.AddPost((new SampleController.Post() { title = "foo", body = "bar", userId = 1 });


//API definition
    [Route("posts")]
    public abstract class SampleController
    {
        //[Route("")]//Optional
		//[HttpGet]//Optional, get is default
        public abstract Task<Post[]> Get();

        [Route("{id}")]
        public abstract Task<Post> GetPost(/*[FromRoute]*/int id);//Optional, FromRoute is implied when name is found in route
		
        //[HttpPost]//Optional, post is implied when using FromBody
        public abstract Task AddPost(/*[FromBody]*/Post value);//FromBody is Optional, is implied when using complex types

        public class Post
        {
            public int userId { get; set; }
            public int id { get; set; }
            public string title { get; set; }
            public string body { get; set; }
        }
    }

Note: the optional attributes are not needed when using JsonHCS wich allows for very easy api clients, BUT Asp.Net might still require them!

A more complete sample can be found in the source.

Plugins

You can now support your own custom types/attributes/requests. Simply create a class that derives from IProxyPlugin:

    /// <summary>
    /// Provides ActionResult support
    /// </summary>
    public class ActionResultPlugin : ProxyPlugin
    {
		...
        public override bool IsHandler => true;
		...
        public override Task<T> Handle<T>(PluginManager manager, JsonHCS jsonHCS, string route, List<Parameter> parameters, IInvocation invocation)
        {
            var targetType = typeof(T);
            //Get HttpResponseMessage with default implementation
            var task = manager.Handle<System.Net.Http.HttpResponseMessage>(jsonHCS, route, parameters, invocation);
            Task<T> returntask;
            //implement own usage
            if (targetType.IsConstructedGenericType)
            {
                returntask = this.GetType().GetMethod("GetActionResultT").MakeGenericMethod(targetType.GetGenericArguments().First()).Invoke(this, new object[] { task, jsonHCS }) as Task<T>;
            }
            else if (typeof(ApiDefinition.ActionResult) == targetType)
            {
                returntask = GetActionResult(task, jsonHCS) as Task<T>;
            }
            else
            {
                returntask = GetIActionResult(task, jsonHCS) as Task<T>;
            }
            return returntask;
        }
		...
    }

And include it in the plugin list when constructing the ProxyGenerator:

JsonHCSProxyGenerator pg = new JsonHCSProxyGenerator(null, new ActionResultPlugin(), new BasicPlugin()); //Don't forget to include the BasicPlugin if you need the default implementations

Plugins are loaded in order, so the first plugin in the list that is able to handle the request will handle it. It is always best to load specific plugins first to avoid priority issues.

By default the following plugins are loaded:

  • ActionResultPlugin
  • BasicPlugin

You can remove them by not including these when specifying your own plugins.

Shared api definition (advanced)

With JsonHCS.Net.Proxies you can share your api definition between your server and client without any code generation!

Make your definition as an abstract class inheriting from Controller or ControllerBase Then add these usings:

#if SERVER
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
#else
using JsonHCSNet.Proxies.ApiDefinition; 
#endif

Example csproj (adjust to your situation):

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard1.5</TargetFramework>
  </PropertyGroup>

  <PropertyGroup Condition="$(DefineConstants.Contains(SERVER))">
    <TargetFramework>netstandard2.0</TargetFramework>
    <AssemblyName>Lib.Server</AssemblyName>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DefineConstants>$(DefineConstants);TRACE;DEBUG</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <DefineConstants>$(DefineConstants);TRACE;RELEASE</DefineConstants>
  </PropertyGroup>

  <ItemGroup Condition="$(DefineConstants.Contains(SERVER))">
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.3" />
  </ItemGroup>

  <ItemGroup Condition="!$(DefineConstants.Contains(SERVER))">
    <PackageReference Include="JsonHCS.Net.Proxies" Version="1.2.0" />
  </ItemGroup>
</Project>

Now you can build (or package) and reference the Library you made twice, one for the client using JsonHCS api definitions and one for the server (you need to tell Visual studio or MSbuild to define SERVER as a compilation constant). In your client you can use the abstract class to generate the proxy as described earlier, in the server you can inherit your implementation from the abstract class you made and no need to define your routes/attributes again as they are set in the abstract class.

Now when you make changes to your definition both api and client will get compile-time checks of valid api implementation/usage without any custom plugins or code generation!

Issues

Found an issue? Submit an issue!

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 was computed.  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. 
.NET Core netcoreapp1.0 was computed.  netcoreapp1.1 was computed.  netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard1.5 is compatible.  netstandard1.6 was computed.  netstandard2.0 was computed.  netstandard2.1 was computed. 
.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 tizen30 was computed.  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 (2)

Showing the top 2 NuGet packages that depend on JsonHCS.Net.Proxies:

Package Downloads
PlugSharp

A c# client library for plug.dj bots or clients

JsonHCS.Net.Proxies.SignalR

A simple JsonHCS.Net.Proxies plugin with strongly typed SignalR hub support

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.9.0 96 10/15/2024
1.8.2 154 8/7/2024
1.8.1 144 8/7/2024
1.8.0 469 10/18/2021
1.7.0 407 4/4/2021
1.6.2 1,177 11/10/2020
1.6.1 996 2/17/2020
1.6.0 613 2/14/2020 1.6.0 is deprecated.
1.5.3 557 11/20/2019
1.5.2 1,116 11/16/2019
1.5.1 1,982 10/23/2019
1.5.0 949 9/25/2019
1.4.0 723 7/9/2019
1.3.0 534 7/1/2019
1.2.0 824 5/22/2019
1.1.1 562 5/15/2019
1.1.0 647 3/7/2019
1.0.9 728 12/10/2018
1.0.8 713 12/6/2018
1.0.6 692 12/6/2018
1.0.5 698 12/4/2018
1.0.4 792 10/12/2018
1.0.0 819 8/23/2018

- Changed plugin api to generic task
- Added ConfigureAwait and minimized blocking