diff --git a/NBitcoin.Tests/AltcoinTests.cs b/NBitcoin.Tests/AltcoinTests.cs
index 54b29ca038..751904ecf9 100644
--- a/NBitcoin.Tests/AltcoinTests.cs
+++ b/NBitcoin.Tests/AltcoinTests.cs
@@ -1,6 +1,5 @@
using NBitcoin.Altcoins.Elements;
using NBitcoin.RPC;
-using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
@@ -8,7 +7,7 @@
using System.Net;
using System.Threading.Tasks;
using NBitcoin.Altcoins;
-using NBitcoin.JsonConverters;
+using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Xunit;
using Encoders = NBitcoin.DataEncoders.Encoders;
diff --git a/NBitcoin/NBitcoin.csproj b/NBitcoin/NBitcoin.csproj
index 7f869f60dc..c11c406056 100644
--- a/NBitcoin/NBitcoin.csproj
+++ b/NBitcoin/NBitcoin.csproj
@@ -52,16 +52,25 @@
$(DefineConstants);NO_RCA;NOPARALLEL;NETSTANDARD;NETSTANDARD1X;NULLABLE_SHIMS;NO_MEM_BUFFER;NOTRACESOURCE;NOCUSTOMSSLVALIDATION;NOSTRNORMALIZE;NOSOCKET;NOFILEIO;USEBC;NODEFAULTRNG;NODYNAMIC;NOX509;NONATIVEHASH;NO_ARRAY_FILL;NO_NATIVE_HMACSHA512;NO_THREAD;NO_NATIVERIPEMD160;NO_NATIVESHA1;NO_SOCKETASYNC
-
+
$(DefineConstants);SECP256K1_VERIFY
+ NOJSONNET
+ true
-
-
+
+
+
+
+
+
+
+
+
diff --git a/NBitcoin/RPC/FundRawTransactionOptions.cs b/NBitcoin/RPC/FundRawTransactionOptions.cs
index 02242fa41b..1e2795b74c 100644
--- a/NBitcoin/RPC/FundRawTransactionOptions.cs
+++ b/NBitcoin/RPC/FundRawTransactionOptions.cs
@@ -1,11 +1,4 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace NBitcoin.RPC
+namespace NBitcoin.RPC
{
public class FundRawTransactionOptions
{
diff --git a/NBitcoin/RPC/ImportMultiAddress.cs b/NBitcoin/RPC/ImportMultiAddress.cs
index 4518c3fd0c..e3600be0c6 100644
--- a/NBitcoin/RPC/ImportMultiAddress.cs
+++ b/NBitcoin/RPC/ImportMultiAddress.cs
@@ -1,13 +1,27 @@
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+
using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+#if !NOJSONNET
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using NBitcoin.JsonConverters;
+#else
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using NBitcoin.SystemJsonConverters;
+#endif
using NBitcoin.Scripting;
namespace NBitcoin.RPC
{
- [JsonObject(MemberSerialization.OptIn)]
+#if !NOJSONNET
+ [JsonElement(MemberSerialization.OptIn)]
+#else
+[JsonConverter(typeof(MemberOptInJsonConverter))]
+#endif
public class ImportMultiAddress
{
public class ScriptPubKeyObject
@@ -27,7 +41,12 @@ public ScriptPubKeyObject(BitcoinAddress address)
[JsonIgnore]
public Script ScriptPubKey { get; set; }
+#if !NOJSONNET
[JsonProperty("address", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("address")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public BitcoinAddress Address { get; set; }
///
@@ -43,39 +62,79 @@ public bool IsAddress
}
}
}
-
+#if !NOJSONNET
[JsonProperty("scriptPubKey", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("scriptPubKey")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
[JsonConverter(typeof(ImportMultiScriptPubKeyConverter))]
public ScriptPubKeyObject ScriptPubKey { get; set; }
///
/// Creation time of the key, keep null if this address has just been generated
///
+#if !NOJSONNET
[JsonProperty("timestamp")]
+#else
+ [JsonPropertyName("timestamp")]
+#endif
public DateTimeOffset? Timestamp { get; set; }
-
+#if !NOJSONNET
[JsonProperty("redeemscript", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("redeemscript")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public Script RedeemScript { get; set; }
-
+#if !NOJSONNET
[JsonProperty("pubkeys", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("pubkeys")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public PubKey[] PubKeys { get; set; }
-
+#if !NOJSONNET
[JsonProperty("keys", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("keys")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public BitcoinSecret[] Keys { get; set; }
-
+#if !NOJSONNET
[JsonProperty("internal", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("internal")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public bool? Internal { get; set; }
-
+#if !NOJSONNET
[JsonProperty("watchonly", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("watchonly")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public bool? WatchOnly { get; set; }
-
+#if !NOJSONNET
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("label")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public string Label { get; set; }
-
+#if !NOJSONNET
[JsonProperty("desc", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("desc")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public OutputDescriptor Desc { get; set; }
-
+#if !NOJSONNET
[JsonProperty("range", NullValueHandling = NullValueHandling.Ignore)]
+#else
+ [JsonPropertyName("range")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+#endif
public int[] Ranges { get; set; }
[JsonIgnore]
diff --git a/NBitcoin/RPC/SignRawTransactionWithKeyRequest.cs b/NBitcoin/RPC/SignRawTransactionWithKeyRequest.cs
index 67b5758359..91b669de46 100644
--- a/NBitcoin/RPC/SignRawTransactionWithKeyRequest.cs
+++ b/NBitcoin/RPC/SignRawTransactionWithKeyRequest.cs
@@ -1,9 +1,4 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace NBitcoin.RPC
+namespace NBitcoin.RPC
{
public class SignRawTransactionRequest
{
diff --git a/NBitcoin/SystemJsonConverters/MemberOptInJsonConverter.cs b/NBitcoin/SystemJsonConverters/MemberOptInJsonConverter.cs
new file mode 100644
index 0000000000..6db7d5ad06
--- /dev/null
+++ b/NBitcoin/SystemJsonConverters/MemberOptInJsonConverter.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace NBitcoin.SystemJsonConverters
+{
+ public class MemberOptInJsonConverter : JsonConverter where T : class
+ {
+ public override bool HandleNull => false;
+
+ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return JsonSerializer.Deserialize(ref reader, options);
+ }
+
+ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
+ {
+ if (value is null) return;
+ writer.WriteStartObject();
+ var type = value.GetType();
+ var props = type.GetProperties();
+
+ foreach (var property in props)
+ {
+ var propValue = property.GetValue(value);
+ var jsonAttribute = property.GetCustomAttribute();
+ if (jsonAttribute is null)
+ {
+ continue;
+ }
+
+ var ignoreAttribute = property.GetCustomAttribute();
+ if (ignoreAttribute is not null)
+ {
+ switch (ignoreAttribute.Condition)
+ {
+ case JsonIgnoreCondition.Never:
+ break;
+ case JsonIgnoreCondition.Always:
+ continue;
+ case JsonIgnoreCondition.WhenWritingDefault:
+ if (propValue == null)
+ {
+ continue;
+ }
+
+ break;
+ case JsonIgnoreCondition.WhenWritingNull:
+
+ if (propValue == default)
+ {
+ continue;
+ }
+
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ switch (true)
+ {
+ case true when propValue is not null:
+ case true when propValue is null && options.DefaultIgnoreCondition == JsonIgnoreCondition.Never:
+ writer.WritePropertyName(property.Name);
+ JsonSerializer.Serialize(writer, propValue, options);
+ break;
+ }
+ }
+
+ writer.WriteEndObject();
+ }
+ }
+
+ public class MemberOptInJsonConverter : JsonConverterFactory
+ {
+ public override bool CanConvert(Type typeToConvert) => !typeToConvert.IsPrimitive;
+
+ public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
+ {
+ JsonConverter converter = (JsonConverter) Activator.CreateInstance(
+ typeof(MemberOptInJsonConverter<>)
+ .MakeGenericType(new Type[] {typeToConvert}),
+ BindingFlags.Instance | BindingFlags.Public,
+ binder: null,
+ args: null,
+ culture: null)!;
+
+ return converter;
+ }
+ }
+}