using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Nethereum.JsonRpc.Client.RpcMessages
{
/*
RPC Model simplified and downported to net351 from EdjCase.JsonRPC.Core
https://github.com/edjCase/JsonRpc/tree/master/src/EdjCase.JsonRpc.Core
The MIT License (MIT)
Copyright(c) 2015 Gekctek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
public static class RpcResponseExtensions
{
///
/// Parses and returns the result of the rpc response as the type specified.
/// Otherwise throws a parsing exception
///
/// Type of object to parse the response as
/// Rpc response object
/// Returns the type's default value if the result is null. Otherwise throws parsing exception
/// Result of response as type specified
public static T GetResult(this RpcResponseMessage response, bool returnDefaultIfNull = true, JsonSerializerSettings settings = null)
{
if (response.Result == null)
{
if (!returnDefaultIfNull && default(T) != null)
{
throw new Exception("Unable to convert the result (null) to type " + typeof(T));
}
return default(T);
}
try
{
if (settings == null)
{
return response.Result.ToObject();
}
else
{
JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
return response.Result.ToObject(jsonSerializer);
}
}
catch (FormatException ex)
{
throw new FormatException("Invalid format when trying to convert the result to type " + typeof(T), ex);
}
catch (Exception ex)
{
throw new Exception("Unable to convert the result to type " + typeof(T), ex);
}
}
///
/// Parses and returns the result of the rpc streaming response as the type specified.
/// Otherwise throws a parsing exception
///
/// Type of object to parse the response as
/// Rpc response object
/// Returns the type's default value if the result is null. Otherwise throws parsing exception
/// Result of response as type specified
public static T GetStreamingResult(this RpcStreamingResponseMessage response, bool returnDefaultIfNull = true, JsonSerializerSettings settings = null)
{
if(response.Method == null) {
return GetResult(response, returnDefaultIfNull, settings);
}
if (response.Params.Result == null)
{
if (!returnDefaultIfNull && default(T) != null)
{
throw new Exception("Unable to convert the result (null) to type " + typeof(T));
}
return default(T);
}
try
{
if (settings == null)
{
return response.Params.Result.ToObject();
}
else
{
JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
return response.Params.Result.ToObject(jsonSerializer);
}
}
catch (FormatException ex)
{
throw new FormatException("Invalid format when trying to convert the result to type " + typeof(T), ex);
}
catch (Exception ex)
{
throw new Exception("Unable to convert the result to type " + typeof(T), ex);
}
}
}
[JsonObject]
public class RpcResponseMessage
{
[JsonConstructor]
protected RpcResponseMessage()
{
JsonRpcVersion = "2.0";
}
/// Request id
protected RpcResponseMessage(object id)
{
this.Id = id;
JsonRpcVersion = "2.0";
}
/// Request id
/// Request error
public RpcResponseMessage(object id, RpcError error) : this(id)
{
this.Error = error;
}
/// Request id
/// Response result object
public RpcResponseMessage(object id, JToken result) : this(id)
{
this.Result = result;
}
///
/// Request id (Required but nullable)
///
[JsonProperty("id", Required = Required.Default)]
public object Id { get; private set; }
///
/// Rpc request version (Required)
///
[JsonProperty("jsonrpc", Required = Required.Always)]
public string JsonRpcVersion { get; private set; }
///
/// Reponse result object (Required)
///
[JsonProperty("result", Required = Required.Default)]
public JToken Result { get; private set; }
///
/// Error from processing Rpc request (Required)
///
[JsonProperty("error", Required = Required.Default)]
public RpcError Error { get; protected set; }
[JsonIgnore]
public bool HasError { get { return this.Error != null; } }
}
[JsonObject]
public class RpcStreamingResponseMessage : RpcResponseMessage
{
[JsonConstructor]
protected RpcStreamingResponseMessage()
{
}
/// Request error
public RpcStreamingResponseMessage(RpcError error) : base()
{
this.Error = error;
}
/// method name
/// Response result object
public RpcStreamingResponseMessage(string method, RpcStreamingParams @params) : base()
{
this.Method = method;
this.Params = @params;
}
///
/// Rpc request version (Required)
///
[JsonProperty("method", Required = Required.Default)]
public string Method { get; private set; }
///
/// Reponse result object (Required)
///
[JsonProperty("params", Required = Required.Default)]
public RpcStreamingParams Params { get; private set; }
}
[JsonObject]
public class RpcStreamingParams
{
[JsonConstructor]
public RpcStreamingParams()
{
}
///
/// Response Subscription Id (Required)
///
[JsonProperty("subscription", Required = Required.Always)]
public string Subscription { get; private set; }
///
/// Reponse result object (Required)
///
[JsonProperty("result", Required = Required.Always)]
public JToken Result { get; private set; }
}
[JsonObject]
public class RpcRequestMessage
{
[JsonConstructor]
private RpcRequestMessage()
{
}
/// Request id
/// Target method name
/// List of parameters for the target method
public RpcRequestMessage(object id, string method, params object[] parameterList)
{
this.Id = id;
this.JsonRpcVersion = "2.0";
this.Method = method;
this.RawParameters = parameterList;
}
/// Request id
/// Target method name
/// Map of parameter name to parameter value for the target method
public RpcRequestMessage(object id, string method, Dictionary parameterMap)
{
this.Id = id;
this.JsonRpcVersion = "2.0";
this.Method = method;
this.RawParameters = parameterMap;
}
///
/// Request Id (Optional)
///
[JsonProperty("id")]
public object Id { get; private set; }
///
/// Version of the JsonRpc to be used (Required)
///
[JsonProperty("jsonrpc", Required = Required.Always)]
public string JsonRpcVersion { get; private set; }
///
/// Name of the target method (Required)
///
[JsonProperty("method", Required = Required.Always)]
public string Method { get; private set; }
///
/// Parameters to invoke the method with (Optional)
///
[JsonProperty("params")]
[JsonConverter(typeof(RpcParametersJsonConverter))]
public object RawParameters { get; private set; }
}
///
/// Json converter for Rpc parameters
///
public class RpcParametersJsonConverter : JsonConverter
{
///
/// Writes the value of the parameters to json format
///
/// Json writer
/// Value to be converted to json format
/// Json serializer
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
///
/// Read the json format and return the correct object type/value for it
///
/// Json reader
/// Type of property being set
/// The current value of the property being set
/// Json serializer
/// The object value of the converted json value
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.StartObject:
try
{
JObject jObject = JObject.Load(reader);
return jObject.ToObject>();
}
catch (Exception)
{
throw new Exception("Request parameters can only be an associative array, list or null.");
}
case JsonToken.StartArray:
return JArray.Load(reader).ToObject