diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml
index c36fc10..8711eff 100644
--- a/.github/workflows/dotnetcore.yml
+++ b/.github/workflows/dotnetcore.yml
@@ -12,7 +12,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
- dotnet-version: 3.1.100
+ dotnet-version: 5.0.100
- name: Build with dotnet
run: dotnet build -c Release
- name: Test with dotnet
diff --git a/demo/reCAPTCHA.Demo/Pages/V2_Checkbox.cshtml.cs b/demo/reCAPTCHA.Demo/Pages/V2_Checkbox.cshtml.cs
index 8a57dd3..538209b 100644
--- a/demo/reCAPTCHA.Demo/Pages/V2_Checkbox.cshtml.cs
+++ b/demo/reCAPTCHA.Demo/Pages/V2_Checkbox.cshtml.cs
@@ -1,6 +1,6 @@
-using System.Threading.Tasks;
+using System.Text.Json;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
-using Newtonsoft.Json;
using Owl.reCAPTCHA;
using Owl.reCAPTCHA.v2;
@@ -22,10 +22,13 @@ public async Task OnPostAsync(string token)
var response = await _siteVerify.Verify(new reCAPTCHASiteVerifyRequest
{
Response = token,
- RemoteIp = HttpContext.Connection.RemoteIpAddress.ToString()
+ RemoteIp = HttpContext.Connection.RemoteIpAddress?.ToString()
});
- Result = JsonConvert.SerializeObject(response, Formatting.Indented);
+ Result = JsonSerializer.Serialize(response, new JsonSerializerOptions
+ {
+ WriteIndented = true
+ });
}
}
-}
\ No newline at end of file
+}
diff --git a/demo/reCAPTCHA.Demo/Pages/V2_Invisible.cshtml.cs b/demo/reCAPTCHA.Demo/Pages/V2_Invisible.cshtml.cs
index 32c9c7e..47d8655 100644
--- a/demo/reCAPTCHA.Demo/Pages/V2_Invisible.cshtml.cs
+++ b/demo/reCAPTCHA.Demo/Pages/V2_Invisible.cshtml.cs
@@ -1,6 +1,6 @@
-using System.Threading.Tasks;
+using System.Text.Json;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
-using Newtonsoft.Json;
using Owl.reCAPTCHA;
using Owl.reCAPTCHA.v2;
@@ -22,10 +22,13 @@ public async Task OnPostAsync(string token)
var response = await _siteVerify.Verify(new reCAPTCHASiteVerifyRequest
{
Response = token,
- RemoteIp = HttpContext.Connection.RemoteIpAddress.ToString()
+ RemoteIp = HttpContext.Connection.RemoteIpAddress?.ToString()
});
- Result = JsonConvert.SerializeObject(response, Formatting.Indented);
+ Result = JsonSerializer.Serialize(response, new JsonSerializerOptions
+ {
+ WriteIndented = true
+ });
}
}
-}
\ No newline at end of file
+}
diff --git a/demo/reCAPTCHA.Demo/Pages/V3.cshtml.cs b/demo/reCAPTCHA.Demo/Pages/V3.cshtml.cs
index dc6f7a2..7c785d3 100644
--- a/demo/reCAPTCHA.Demo/Pages/V3.cshtml.cs
+++ b/demo/reCAPTCHA.Demo/Pages/V3.cshtml.cs
@@ -1,6 +1,6 @@
-using System.Threading.Tasks;
+using System.Text.Json;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
-using Newtonsoft.Json;
using Owl.reCAPTCHA;
using Owl.reCAPTCHA.v3;
@@ -22,10 +22,13 @@ public async Task OnPostAsync(string token)
var response = await _siteVerify.Verify(new reCAPTCHASiteVerifyRequest
{
Response = token,
- RemoteIp = HttpContext.Connection.RemoteIpAddress.ToString()
+ RemoteIp = HttpContext.Connection.RemoteIpAddress?.ToString()
});
- Result = JsonConvert.SerializeObject(response, Formatting.Indented);
+ Result = JsonSerializer.Serialize(response, new JsonSerializerOptions
+ {
+ WriteIndented = true
+ });
}
}
-}
\ No newline at end of file
+}
diff --git a/demo/reCAPTCHA.Demo/Pages/V3_Programmatically.cshtml.cs b/demo/reCAPTCHA.Demo/Pages/V3_Programmatically.cshtml.cs
index f23d1a4..e132779 100644
--- a/demo/reCAPTCHA.Demo/Pages/V3_Programmatically.cshtml.cs
+++ b/demo/reCAPTCHA.Demo/Pages/V3_Programmatically.cshtml.cs
@@ -1,6 +1,6 @@
-using System.Threading.Tasks;
+using System.Text.Json;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.RazorPages;
-using Newtonsoft.Json;
using Owl.reCAPTCHA;
using Owl.reCAPTCHA.v3;
@@ -22,10 +22,13 @@ public async Task OnPostAsync(string token)
var response = await _siteVerify.Verify(new reCAPTCHASiteVerifyRequest
{
Response = token,
- RemoteIp = HttpContext.Connection.RemoteIpAddress.ToString()
+ RemoteIp = HttpContext.Connection.RemoteIpAddress?.ToString()
});
- Result = JsonConvert.SerializeObject(response, Formatting.Indented);
+ Result = JsonSerializer.Serialize(response, new JsonSerializerOptions
+ {
+ WriteIndented = true
+ });
}
}
}
diff --git a/demo/reCAPTCHA.Demo/Startup.cs b/demo/reCAPTCHA.Demo/Startup.cs
index f152444..6952e4a 100644
--- a/demo/reCAPTCHA.Demo/Startup.cs
+++ b/demo/reCAPTCHA.Demo/Startup.cs
@@ -19,7 +19,7 @@ public Startup(IConfiguration configuration)
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
- services.AddRazorPages().AddRazorRuntimeCompilation();
+ services.AddRazorPages();
services.AddreCAPTCHAV3(x =>
{
diff --git a/demo/reCAPTCHA.Demo/reCAPTCHA.Demo.csproj b/demo/reCAPTCHA.Demo/reCAPTCHA.Demo.csproj
index 491fe10..caaf366 100644
--- a/demo/reCAPTCHA.Demo/reCAPTCHA.Demo.csproj
+++ b/demo/reCAPTCHA.Demo/reCAPTCHA.Demo.csproj
@@ -4,16 +4,6 @@
net5.0
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
diff --git a/src/Owl.reCAPTCHA/Owl.reCAPTCHA.csproj b/src/Owl.reCAPTCHA/Owl.reCAPTCHA.csproj
index d286373..8f3573e 100644
--- a/src/Owl.reCAPTCHA/Owl.reCAPTCHA.csproj
+++ b/src/Owl.reCAPTCHA/Owl.reCAPTCHA.csproj
@@ -5,24 +5,20 @@
Owl.reCAPTCHA
Owl.reCAPTCHA
maliming
- reCAPTCHA for Asp Net Core 3.0
+ reCAPTCHA for Asp Net Core 5.0
https://github.com/maliming/reCAPTCHA
https://github.com/maliming/reCAPTCHA
git
- 0.3.0
+ 0.4.0
true
Library
true
true
-
- $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
- 0.3.1
+ 0.4.0
-
-
-
+
diff --git a/src/Owl.reCAPTCHA/reCAPTCHASiteVerifyResponse.cs b/src/Owl.reCAPTCHA/reCAPTCHASiteVerifyResponse.cs
index 711820b..c446e3d 100644
--- a/src/Owl.reCAPTCHA/reCAPTCHASiteVerifyResponse.cs
+++ b/src/Owl.reCAPTCHA/reCAPTCHASiteVerifyResponse.cs
@@ -1,5 +1,4 @@
using System;
-using Newtonsoft.Json;
namespace Owl.reCAPTCHA
{
@@ -9,13 +8,11 @@ public class reCAPTCHASiteVerifyResponse
public bool Success { get; set; }
// timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
- [JsonProperty("challenge_ts")]
public DateTime ChallengeTs { get; set; }
// the hostname of the site where the reCAPTCHA was solved
public string HostName { get; set; }
- [JsonProperty("error-codes")]
public string[] ErrorCodes { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Owl.reCAPTCHA/reCAPTCHASiteVerifyResponseJsonConverter.cs b/src/Owl.reCAPTCHA/reCAPTCHASiteVerifyResponseJsonConverter.cs
new file mode 100644
index 0000000..5986e45
--- /dev/null
+++ b/src/Owl.reCAPTCHA/reCAPTCHASiteVerifyResponseJsonConverter.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Owl.reCAPTCHA.v3;
+
+namespace Owl.reCAPTCHA
+{
+ public class reCAPTCHASiteVerifyResponseJsonConverter : JsonConverter
+ {
+ public override bool CanConvert(Type typeToConvert)
+ {
+ return typeToConvert == typeof(reCAPTCHASiteVerifyV3Response) ||
+ typeToConvert == typeof(reCAPTCHASiteVerifyResponse);
+ }
+
+ public override reCAPTCHASiteVerifyResponse Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var rootElement = JsonDocument.ParseValue(ref reader).RootElement;
+
+ var success = rootElement.EnumerateObject().FirstOrDefault(x => x.Name.Equals("success", StringComparison.InvariantCultureIgnoreCase));
+ var challengeTimestamp = rootElement.EnumerateObject().FirstOrDefault(x => x.Name.Equals("challenge_ts", StringComparison.InvariantCultureIgnoreCase));
+ var hostname = rootElement.EnumerateObject().FirstOrDefault(x => x.Name.Equals("hostname", StringComparison.InvariantCultureIgnoreCase));
+ var errorCodes = rootElement.EnumerateObject().FirstOrDefault(x => x.Name.Equals("error-codes", StringComparison.InvariantCultureIgnoreCase));
+
+ if (typeToConvert == typeof(reCAPTCHASiteVerifyResponse))
+ {
+ return new reCAPTCHASiteVerifyResponse
+ {
+ Success = success.Value.ValueKind == JsonValueKind.True,
+ ChallengeTs = challengeTimestamp.Value.ValueKind == JsonValueKind.String ? challengeTimestamp.Value.GetDateTime() : DateTime.MinValue,
+ HostName = hostname.Value.ValueKind == JsonValueKind.String ? hostname.Value.GetString() : null,
+ ErrorCodes = errorCodes.Value.ValueKind == JsonValueKind.Array ? JsonSerializer.Deserialize(errorCodes.Value.GetRawText()) : null
+ };
+ }
+
+ if (typeToConvert == typeof(reCAPTCHASiteVerifyV3Response))
+ {
+ var score = rootElement.EnumerateObject().FirstOrDefault(x => x.Name.Equals("score", StringComparison.InvariantCultureIgnoreCase));
+ var action = rootElement.EnumerateObject().FirstOrDefault(x => x.Name.Equals("action", StringComparison.InvariantCultureIgnoreCase));
+ return new reCAPTCHASiteVerifyV3Response
+ {
+ Success = success.Value.ValueKind == JsonValueKind.True,
+ ChallengeTs = challengeTimestamp.Value.ValueKind == JsonValueKind.String ? challengeTimestamp.Value.GetDateTime() : DateTime.MinValue,
+ HostName = hostname.Value.ValueKind == JsonValueKind.String ? hostname.Value.GetString() : null,
+ ErrorCodes = errorCodes.Value.ValueKind == JsonValueKind.Array ? JsonSerializer.Deserialize(errorCodes.Value.GetRawText()) : null,
+ Score = score.Value.ValueKind == JsonValueKind.Number ? score.Value.GetSingle() : 0,
+ Action = action.Value.ValueKind == JsonValueKind.String ? action.Value.GetString() : null
+ };
+ }
+
+ throw new JsonException($"Incorrect type: {typeToConvert.FullName}");
+ }
+
+ public override void Write(Utf8JsonWriter writer, reCAPTCHASiteVerifyResponse value, JsonSerializerOptions options)
+ {
+ JsonSerializer.Serialize(writer, value);
+ }
+ }
+}
diff --git a/src/Owl.reCAPTCHA/v2/reCAPTCHASiteVerifyV2.cs b/src/Owl.reCAPTCHA/v2/reCAPTCHASiteVerifyV2.cs
index b7ecd95..2df4ee5 100644
--- a/src/Owl.reCAPTCHA/v2/reCAPTCHASiteVerifyV2.cs
+++ b/src/Owl.reCAPTCHA/v2/reCAPTCHASiteVerifyV2.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
+using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
-using Newtonsoft.Json;
namespace Owl.reCAPTCHA.v2
{
@@ -31,8 +31,9 @@ public async Task Verify(reCAPTCHASiteVerifyRequest
var v3Response = await _client.PostAsync("recaptcha/api/siteverify", content);
if (v3Response.IsSuccessStatusCode)
{
- return JsonConvert.DeserializeObject(
- await v3Response.Content.ReadAsStringAsync());
+ var options = new JsonSerializerOptions();
+ options.Converters.Add(new reCAPTCHASiteVerifyResponseJsonConverter());
+ return JsonSerializer.Deserialize(await v3Response.Content.ReadAsStringAsync(), options);
}
return new reCAPTCHASiteVerifyResponse
@@ -45,4 +46,4 @@ public async Task Verify(reCAPTCHASiteVerifyRequest
};
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Owl.reCAPTCHA/v3/reCAPTCHASiteVerifyV3.cs b/src/Owl.reCAPTCHA/v3/reCAPTCHASiteVerifyV3.cs
index 934ea83..1585263 100644
--- a/src/Owl.reCAPTCHA/v3/reCAPTCHASiteVerifyV3.cs
+++ b/src/Owl.reCAPTCHA/v3/reCAPTCHASiteVerifyV3.cs
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
+using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
-using Newtonsoft.Json;
namespace Owl.reCAPTCHA.v3
{
@@ -31,8 +31,9 @@ public async Task Verify(reCAPTCHASiteVerifyReque
var v3Response = await _client.PostAsync("recaptcha/api/siteverify", content);
if (v3Response.IsSuccessStatusCode)
{
- return JsonConvert.DeserializeObject(
- await v3Response.Content.ReadAsStringAsync());
+ var options = new JsonSerializerOptions();
+ options.Converters.Add(new reCAPTCHASiteVerifyResponseJsonConverter());
+ return JsonSerializer.Deserialize(await v3Response.Content.ReadAsStringAsync(), options);
}
return new reCAPTCHASiteVerifyV3Response
@@ -45,4 +46,4 @@ public async Task Verify(reCAPTCHASiteVerifyReque
};
}
}
-}
\ No newline at end of file
+}