diff --git a/Akismet.Net/Akismet.Net.csproj b/Akismet.Net/Akismet.Net.csproj
index cb673df..e043a97 100644
--- a/Akismet.Net/Akismet.Net.csproj
+++ b/Akismet.Net/Akismet.Net.csproj
@@ -8,26 +8,28 @@
MIT
https://github.com/ahwm/Akismet.Net
https://github.com/ahwm/Akismet.Net
- net452;net6.0;netstandard2.0;net7.0
+ net462;netstandard2.0;
(c) 2021 Adam Humpherys
akismet spam antispam
- Dropped explicit support for .NET Core 3.1 and .NET 5 and added support for .NET 7
+ Dropped explicit support for .NET Core; dropped dependency on RestSharp
AkismetApi.Net
- 3.0.0.1
- 3.0.0.0
+ 4.0.0
+ 4.0.0.0
README.md
+
+
+ NETSTANDARD;NETSTANDARD2_0
+
+
+
+
+
-
- 106.15.0
-
-
- 13.0.3
-
-
- 4.7.0
-
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -35,6 +37,12 @@
+
+
+
+ <_Parameter1>GodaddyWrapper.Tests
+
+
diff --git a/Akismet.Net/AkismetClient.cs b/Akismet.Net/AkismetClient.cs
index 4a60811..84a0383 100644
--- a/Akismet.Net/AkismetClient.cs
+++ b/Akismet.Net/AkismetClient.cs
@@ -1,11 +1,16 @@
using Akismet.Net.Helpers;
-using Newtonsoft.Json;
-using RestSharp;
+#if NETSTANDARD
+using Microsoft.Extensions.Options;
+#endif
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
using System.Reflection;
+using System.Text.Json;
using System.Threading.Tasks;
+using System.Xml.Linq;
namespace Akismet.Net
{
@@ -18,8 +23,9 @@ public class AkismetClient
private readonly string apiKey;
private readonly string[] allowedIntervals = new[] { "60-days", "6-months", "all" };
- private readonly RestClient client;
+ private readonly HttpClient client;
+#if !NETSTANDARD
///
///
///
@@ -31,38 +37,42 @@ public AkismetClient(string apiKey, Uri blogUrl, string applicationName)
this.apiKey = apiKey;
this.blogUrl = blogUrl?.ToString() ?? throw new ArgumentNullException("blogUrl");
- client = new RestClient($"https://{apiKey}.rest.akismet.com/1.1")
+ client = new HttpClient()
{
- UserAgent = $"{applicationName} | Akismet.NET/{Assembly.GetExecutingAssembly().GetName().Version} (https://github.com/ahwm/Akismet.Net)",
+ BaseAddress = new Uri($"https://{apiKey}.rest.akismet.com/1.1/"),
};
+ client.DefaultRequestHeaders.Add("User-Agent", $"{applicationName} | Akismet.NET/{Assembly.GetExecutingAssembly().GetName().Version} (https://github.com/ahwm/Akismet.Net)");
}
-
+#else
///
- /// Verify key
+ ///
///
- ///
- public async Task VerifyKeyAsync()
+ ///
+ ///
+ ///
+ public AkismetClient(HttpClient _httpClient, IOptions options)
{
- var req = new RestRequest("verify-key", Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
- var resp = await client.ExecuteAsync(req);
+ this.apiKey = options.Value.Key;
+ this.blogUrl = options.Value.BlogUrl;
- return resp.Content == "valid";
+ client = _httpClient;
}
+#endif
///
/// Verify key
///
///
- public bool VerifyKey()
+ public async Task VerifyKeyAsync()
{
- var req = new RestRequest("verify-key", Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
- var resp = client.Execute(req);
+ var formData = new FormUrlEncodedContent(new List>
+ {
+ new KeyValuePair("key", apiKey),
+ new KeyValuePair("blog", blogUrl)
+ });
+ var resp = await client.PostAsync("verify-key", formData);
- return resp.Content == "valid";
+ return await resp.Content.ReadAsStringAsync() == "valid";
}
///
@@ -72,67 +82,32 @@ public bool VerifyKey()
///
public async Task CheckAsync(AkismetComment comment)
{
- var req = new RestRequest("comment-check", Method.POST)
- .AddParameter("blog", blogUrl);
-
- var attributes = AttributeHelper.GetAttributes(comment);
- foreach (var kv in attributes)
- req.AddParameter(kv.Key, kv.Value);
-
- var resp = await client.ExecuteAsync(req);
-
- AkismetResponse response = new AkismetResponse();
-
- if (!Boolean.TryParse(resp.Content, out bool result))
+ var data = new List>
{
- response.AkismetErrors.Add(resp.Content);
- response.SpamStatus = SpamStatus.Unspecified;
- }
- else
- response.SpamStatus = result ? SpamStatus.Spam : SpamStatus.Ham;
-
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-debug-help"))
- response.AkismetDebugHelp = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-debug-help").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-pro-tip"))
- response.ProTip = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-alert-code"))
- response.AkismetErrors.Add(resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
-
- return response;
- }
-
- ///
- /// Check comment
- ///
- ///
- ///
- public AkismetResponse Check(AkismetComment comment)
- {
- var req = new RestRequest("comment-check", Method.POST)
- .AddParameter("blog", blogUrl);
+ new KeyValuePair("blog", blogUrl)
+ };
- var attributes = AttributeHelper.GetAttributes(comment);
- foreach (var kv in attributes)
- req.AddParameter(kv.Key, kv.Value);
+ data.AddRange(AttributeHelper.GetAttributes(comment));
- var resp = client.Execute(req);
+ var resp = await client.PostAsync("comment-check", new FormUrlEncodedContent(data));
AkismetResponse response = new AkismetResponse();
+ var responseData = await resp.Content.ReadAsStringAsync();
- if (!Boolean.TryParse(resp.Content, out bool result))
+ if (!Boolean.TryParse(responseData, out bool result))
{
- response.AkismetErrors.Add(resp.Content);
+ response.AkismetErrors.Add(responseData);
response.SpamStatus = SpamStatus.Unspecified;
}
else
response.SpamStatus = result ? SpamStatus.Spam : SpamStatus.Ham;
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-debug-help"))
- response.AkismetDebugHelp = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-debug-help").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-pro-tip"))
- response.ProTip = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-alert-code"))
- response.AkismetErrors.Add(resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-debug-help"))
+ response.AkismetDebugHelp = resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-debug-help").First().Value.ToString();
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-pro-tip"))
+ response.ProTip = resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-alert-code"))
+ response.AkismetErrors.Add(resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
return response;
}
@@ -144,67 +119,32 @@ public AkismetResponse Check(AkismetComment comment)
///
public async Task SubmitSpamAsync(AkismetComment comment)
{
- var req = new RestRequest("submit-spam", Method.POST)
- .AddParameter("blog", blogUrl);
-
- var attributes = AttributeHelper.GetAttributes(comment);
- foreach (var kv in attributes)
- req.AddParameter(kv.Key, kv.Value);
-
- var resp = await client.ExecuteAsync(req);
-
- AkismetResponse response = new AkismetResponse();
-
- if (!Boolean.TryParse(resp.Content, out bool result))
+ var data = new List>
{
- response.AkismetErrors.Add(resp.Content);
- response.SpamStatus = SpamStatus.Unspecified;
- }
- else
- response.SpamStatus = result ? SpamStatus.Spam : SpamStatus.Ham;
-
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-debug-help"))
- response.AkismetDebugHelp = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-debug-help").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-pro-tip"))
- response.ProTip = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-alert-code"))
- response.AkismetErrors.Add(resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
-
- return response;
- }
-
- ///
- /// Submit missed spam
- ///
- ///
- ///
- public AkismetResponse SubmitSpam(AkismetComment comment)
- {
- var req = new RestRequest("submit-spam", Method.POST)
- .AddParameter("blog", blogUrl);
+ new KeyValuePair("blog", blogUrl)
+ };
- var attributes = AttributeHelper.GetAttributes(comment);
- foreach (var kv in attributes)
- req.AddParameter(kv.Key, kv.Value);
+ data.AddRange(AttributeHelper.GetAttributes(comment));
- var resp = client.Execute(req);
+ var resp = await client.PostAsync("submit-spam", new FormUrlEncodedContent(data));
AkismetResponse response = new AkismetResponse();
+ var responseData = await resp.Content.ReadAsStringAsync();
- if (!Boolean.TryParse(resp.Content, out bool result))
+ if (!Boolean.TryParse(responseData, out bool result))
{
- response.AkismetErrors.Add(resp.Content);
+ response.AkismetErrors.Add(responseData);
response.SpamStatus = SpamStatus.Unspecified;
}
else
response.SpamStatus = result ? SpamStatus.Spam : SpamStatus.Ham;
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-debug-help"))
- response.AkismetDebugHelp = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-debug-help").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-pro-tip"))
- response.ProTip = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-alert-code"))
- response.AkismetErrors.Add(resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-debug-help"))
+ response.AkismetDebugHelp = resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-debug-help").First().Value.ToString();
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-pro-tip"))
+ response.ProTip = resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-alert-code"))
+ response.AkismetErrors.Add(resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
return response;
}
@@ -216,67 +156,32 @@ public AkismetResponse SubmitSpam(AkismetComment comment)
///
public async Task SubmitHamAsync(AkismetComment comment)
{
- var req = new RestRequest("submit-ham", Method.POST)
- .AddParameter("blog", blogUrl);
-
- var attributes = AttributeHelper.GetAttributes(comment);
- foreach (var kv in attributes)
- req.AddParameter(kv.Key, kv.Value);
-
- var resp = await client.ExecuteAsync(req);
-
- AkismetResponse response = new AkismetResponse();
-
- if (!Boolean.TryParse(resp.Content, out bool result))
+ var data = new List>
{
- response.AkismetErrors.Add(resp.Content);
- response.SpamStatus = SpamStatus.Unspecified;
- }
- else
- response.SpamStatus = result ? SpamStatus.Spam : SpamStatus.Ham;
-
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-debug-help"))
- response.AkismetDebugHelp = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-debug-help").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-pro-tip"))
- response.ProTip = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-alert-code"))
- response.AkismetErrors.Add(resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
-
- return response;
- }
-
- ///
- /// Submit false positive (ham marked as spam)
- ///
- ///
- ///
- public AkismetResponse SubmitHam(AkismetComment comment)
- {
- var req = new RestRequest("submit-ham", Method.POST)
- .AddParameter("blog", blogUrl);
+ new KeyValuePair("blog", blogUrl)
+ };
- var attributes = AttributeHelper.GetAttributes(comment);
- foreach (var kv in attributes)
- req.AddParameter(kv.Key, kv.Value);
+ data.AddRange(AttributeHelper.GetAttributes(comment));
- var resp = client.Execute(req);
+ var resp = await client.PostAsync("submit-ham", new FormUrlEncodedContent(data));
AkismetResponse response = new AkismetResponse();
+ var responseData = await resp.Content.ReadAsStringAsync();
- if (!Boolean.TryParse(resp.Content, out bool result))
+ if (!Boolean.TryParse(responseData, out bool result))
{
- response.AkismetErrors.Add(resp.Content);
+ response.AkismetErrors.Add(responseData);
response.SpamStatus = SpamStatus.Unspecified;
}
else
response.SpamStatus = result ? SpamStatus.Spam : SpamStatus.Ham;
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-debug-help"))
- response.AkismetDebugHelp = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-debug-help").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-pro-tip"))
- response.ProTip = resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
- if (resp.Headers.Any(r => r.Name.ToLower() == "x-akismet-alert-code"))
- response.AkismetErrors.Add(resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Name.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-debug-help"))
+ response.AkismetDebugHelp = resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-debug-help").First().Value.ToString();
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-pro-tip"))
+ response.ProTip = resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-pro-tip").First().Value.ToString();
+ if (resp.Headers.Any(r => r.Key.ToLower() == "x-akismet-alert-code"))
+ response.AkismetErrors.Add(resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-alert-code").First().Value.ToString() + ": " + resp.Headers.Where(r => r.Key.ToLower() == "x-akismet-alert-msg").First().Value.ToString());
return response;
}
@@ -287,39 +192,13 @@ public AkismetResponse SubmitHam(AkismetComment comment)
///
public async Task GetAccountStatusAsync()
{
- var req = new RestRequest("get-subscription", Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
-
- var resp = await client.ExecuteAsync(req);
- dynamic data = JsonConvert.DeserializeObject(resp.Content);
-
- AkismetAccount account = new AkismetAccount
+ var formData = new FormUrlEncodedContent(new List>
{
- AccountId = (int)data["account_id"],
- AccountName = (string)data["account_name"],
- AccountType = (string)data["account_type"],
- Status = (string)data["status"],
- LimitReached = (bool)data["limit_reached"]
- };
- if (!(data["next_billing_date"] is bool))
- account.NextBillingDate = DateTimeHelper.UnixTimeStampToDateTime(Convert.ToInt32(data["next_billing_date"]));
-
- return account;
- }
-
- ///
- ///
- ///
- ///
- public AkismetAccount GetAccountStatus()
- {
- var req = new RestRequest("get-subscription", Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
-
- var resp = client.Execute(req);
- dynamic data = JsonConvert.DeserializeObject(resp.Content);
+ new KeyValuePair("key", apiKey),
+ new KeyValuePair("blog", blogUrl)
+ });
+ var resp = await client.PostAsync("get-subscription", formData);
+ var data = JsonSerializer.Deserialize>(await resp.Content.ReadAsStringAsync());
AkismetAccount account = new AkismetAccount
{
@@ -345,40 +224,18 @@ public async Task GetStatisticsAsync(string interval = "")
if (!String.IsNullOrWhiteSpace(interval) && !allowedIntervals.Contains(interval))
throw new ArgumentException("Invalid interval", nameof(interval));
- var req = new RestRequest("get-stats", Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
-
- if (!String.IsNullOrWhiteSpace(interval))
- req.AddParameter("from", interval);
-
- var resp = await client.ExecuteAsync(req);
- var data = JsonConvert.DeserializeObject(resp.Content);
-
- return data;
- }
-
- ///
- ///
- ///
- /// Allowed options: 60-days, 6-months, all
- ///
- public SpamStats GetStatistics(string interval = "")
- {
- if (!String.IsNullOrWhiteSpace(interval) && !allowedIntervals.Contains(interval))
- throw new ArgumentException("Invalid interval", nameof(interval));
-
- var req = new RestRequest("get-stats", Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
-
+ var data = new List>
+ {
+ new KeyValuePair("key", apiKey),
+ new KeyValuePair("blog", blogUrl)
+ };
if (!String.IsNullOrWhiteSpace(interval))
- req.AddParameter("from", interval);
+ data.Add(new KeyValuePair("from", interval));
+ var resp = await client.PostAsync("get-stats", new FormUrlEncodedContent(data));
- var resp = client.Execute(req);
- var data = JsonConvert.DeserializeObject(resp.Content);
+ var stats = JsonSerializer.Deserialize(await resp.Content.ReadAsStringAsync());
- return data;
+ return stats;
}
///
@@ -387,64 +244,38 @@ public SpamStats GetStatistics(string interval = "")
///
public async Task DecativateAsync()
{
- var req = new RestRequest("deactivate", Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
-
- var resp = await client.ExecuteAsync(req);
-
- return resp.Content;
- }
-
- ///
- ///
- ///
- ///
- public string Deactivate()
- {
- var req = new RestRequest("deactivate", Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
+ var formData = new FormUrlEncodedContent(new List>
+ {
+ new KeyValuePair("key", apiKey),
+ new KeyValuePair("blog", blogUrl)
+ });
- var resp = client.Execute(req);
+ var resp = await client.PostAsync("deactivate", formData);
- return resp.Content;
+ return await resp.Content.ReadAsStringAsync();
}
///
///
///
///
- public async Task CustomCallAsync(string command, Dictionary attributes)
+ public async Task CustomCallAsync(string command, Dictionary attributes)
{
- var req = new RestRequest(command, Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
-
- foreach (var kv in attributes)
- req.AddParameter(kv.Key, kv.Value);
-
- RestResponse resp = (RestResponse)await client.ExecuteAsync(req);
+ var data = new List>
+ {
+ new KeyValuePair("key", apiKey),
+ new KeyValuePair("blog", blogUrl)
+ };
+ data.AddRange(attributes);
+ var resp = await client.PostAsync(command, new FormUrlEncodedContent(data));
- return resp;
+ return await resp.Content.ReadAsStringAsync();
}
+ }
- ///
- ///
- ///
- ///
- public RestResponse CustomCall(string command, Dictionary attributes)
- {
- var req = new RestRequest(command, Method.POST)
- .AddParameter("key", apiKey)
- .AddParameter("blog", blogUrl);
-
- foreach (var kv in attributes)
- req.AddParameter(kv.Key, kv.Value);
-
- RestResponse resp = (RestResponse)client.Execute(req);
-
- return resp;
- }
+ public class AkismetClientOptions
+ {
+ public string Key { get; set; } = "";
+ public string BlogUrl { get; set; } = "";
}
}
diff --git a/Akismet.Net/AkismetComment.cs b/Akismet.Net/AkismetComment.cs
index e06c309..3a3b5b7 100644
--- a/Akismet.Net/AkismetComment.cs
+++ b/Akismet.Net/AkismetComment.cs
@@ -1,7 +1,8 @@
using Akismet.Net.Attributes;
using Akismet.Net.Helpers;
-using Newtonsoft.Json;
using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
namespace Akismet.Net
{
@@ -123,14 +124,14 @@ public override string ToString()
{
var attributes = AttributeHelper.GetAttributes(this);
- return JsonConvert.SerializeObject(attributes);
+ return JsonSerializer.Serialize(attributes);
}
}
///
///
///
- public class CommentTypeConverter : JsonConverter
+ public class CommentTypeConverter : JsonConverter
{
///
///
@@ -142,35 +143,15 @@ public override bool CanConvert(Type objectType)
return objectType == typeof(AkismentCommentType);
}
- ///
- ///
- ///
- public override bool CanRead => false;
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override AkismentCommentType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
- ///
- ///
- ///
- ///
- ///
- ///
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void Write(Utf8JsonWriter writer, AkismentCommentType value, JsonSerializerOptions options)
{
string commentType = (AkismentCommentType)value;
- writer.WriteValue(commentType);
+ writer.WriteStringValue(commentType);
}
}
}
diff --git a/Akismet.Net/Helpers/AttributeHelper.cs b/Akismet.Net/Helpers/AttributeHelper.cs
index 4d108e7..9c9ba7a 100644
--- a/Akismet.Net/Helpers/AttributeHelper.cs
+++ b/Akismet.Net/Helpers/AttributeHelper.cs
@@ -1,5 +1,4 @@
using Akismet.Net.Attributes;
-using RestSharp.Extensions;
using System.Collections.Generic;
using System.Reflection;
@@ -25,7 +24,7 @@ public static List> GetAttributes(object model)
}
else
{
- if (property.GetAttribute() is AkismetNameAttribute attribute)
+ if (property.GetCustomAttribute(typeof(AkismetNameAttribute)) is AkismetNameAttribute attribute)
l.Add(new KeyValuePair(attribute.AkismetName, property.GetValue(model).ToString()));
else
l.Add(new KeyValuePair(property.Name, property.GetValue(model).ToString()));
diff --git a/Akismet.Net/Services.cs b/Akismet.Net/Services.cs
new file mode 100644
index 0000000..e4d6199
--- /dev/null
+++ b/Akismet.Net/Services.cs
@@ -0,0 +1,36 @@
+#if NETSTANDARD
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Reflection;
+
+namespace Akismet.Net
+{
+ public static class ServicesExtension
+ {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static IServiceCollection AddAkismet(this IServiceCollection services, string key, string applicationName, string blogUrl)
+ {
+ // https://stackoverflow.com/a/79111722/1892993
+ services.AddOptions()
+ .Configure(options => {
+ options.Key = key;
+ options.BlogUrl = blogUrl;
+ });
+ services.AddHttpClient(client =>
+ {
+ client.BaseAddress = new Uri($"https://{key}.rest.akismet.com/1.1/");
+ client.DefaultRequestHeaders.Add("User-Agent", $"{applicationName} | Akismet.NET/{Assembly.GetExecutingAssembly().GetName().Version} (https://github.com/ahwm/Akismet.Net)");
+ });
+
+ return services;
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Akismet.Net/SpamStatistics.cs b/Akismet.Net/SpamStatistics.cs
index e210704..3919ad5 100644
--- a/Akismet.Net/SpamStatistics.cs
+++ b/Akismet.Net/SpamStatistics.cs
@@ -1,7 +1,7 @@
-using Newtonsoft.Json;
-using System;
+using System;
using System.Collections.Generic;
using System.Text;
+using System.Text.Json.Serialization;
namespace Akismet.Net
{
@@ -23,13 +23,13 @@ public partial class SpamStats
///
///
///
- [JsonProperty("missed_spam")]
+ [JsonPropertyName("missed_spam")]
public long MissedSpam { get; set; }
///
///
///
- [JsonProperty("false_positives")]
+ [JsonPropertyName("false_positives")]
public long FalsePositives { get; set; }
///
@@ -45,7 +45,7 @@ public partial class SpamStats
///
///
///
- [JsonProperty("time_saved")]
+ [JsonPropertyName("time_saved")]
public long TimeSaved { get; set; }
}
@@ -67,13 +67,13 @@ public partial class Breakdown
///
///
///
- [JsonProperty("missed_spam")]
+ [JsonPropertyName("missed_spam")]
public long MissedSpam { get; set; }
///
///
///
- [JsonProperty("false_positives")]
+ [JsonPropertyName("false_positives")]
public long FalsePositives { get; set; }
///
diff --git a/Akismet.Tests/Akismet.Tests.csproj b/Akismet.Tests/Akismet.Tests.csproj
index d206d64..3235fce 100644
--- a/Akismet.Tests/Akismet.Tests.csproj
+++ b/Akismet.Tests/Akismet.Tests.csproj
@@ -1,11 +1,15 @@
- net7.0;net6.0;net462
+ net9.0;net8.0;net6.0;net462
false
+
+ NETCORE
+
+
@@ -19,6 +23,8 @@
all
+
+
diff --git a/Akismet.Tests/AkismetTests.cs b/Akismet.Tests/AkismetTests.cs
index 74c3caf..8ed4cd6 100644
--- a/Akismet.Tests/AkismetTests.cs
+++ b/Akismet.Tests/AkismetTests.cs
@@ -1,10 +1,6 @@
using Akismet.Net;
using Shouldly;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
using System.Threading.Tasks;
using Xunit;
@@ -12,9 +8,15 @@ namespace Akismet.Tests
{
public class AkismetTests
{
- private readonly string ApiKey;
private readonly string ApiKeyUrl;
private readonly AkismetClient Client;
+#if NETCORE
+ public AkismetTests(AkismetClient akismetClient)
+ {
+ Client = akismetClient;
+ }
+#else
+ private readonly string ApiKey;
public AkismetTests()
{
@@ -23,12 +25,7 @@ public AkismetTests()
Client = new AkismetClient(ApiKey, new Uri(ApiKeyUrl), "Akismet Test Application");
}
-
- [Fact]
- public void VerifyKeyTest()
- {
- Client.VerifyKey().ShouldBe(true);
- }
+#endif
[Fact]
public async Task VerifyKeyAsyncTest()
@@ -38,29 +35,6 @@ public async Task VerifyKeyAsyncTest()
isValid.ShouldBe(true);
}
- [Fact]
- public void CheckSpamComment()
- {
- AkismetComment comment = new AkismetComment
-{
- CommentAuthor = "viagra-test-123",
- CommentAuthorEmail = "akismet-guaranteed-spam@example.com",
- CommentAuthorUrl = "http://www.spamwebsite.com",
- Referrer = "https://www.google.com",
- UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36",
- CommentContent = "This is a test spam comment",
- CommentType = AkismentCommentType.ContactForm, // multiple defined values, or use new AkismetCommentType("new-comment-type") for a custom option
- Permalink = $"{ApiKeyUrl}/contact",
- IsTest = "true",
- BlogCharset = "UTF-8",
- BlogLanguage = "en-US",
- CommentDate = DateTime.UtcNow.ToString("s"), // ISO-8601 format
- CommentPostModified = DateTime.UtcNow.ToString("s") // ISO-8601 format
- };
- var spamResult = Client.Check(comment);
- spamResult.SpamStatus.ShouldBe(SpamStatus.Spam);
- }
-
[Fact]
public async Task CheckSpamCommentAsync()
{
@@ -84,30 +58,6 @@ public async Task CheckSpamCommentAsync()
spamResult.SpamStatus.ShouldBe(SpamStatus.Spam);
}
- [Fact]
- public void CheckHamComment()
- {
- AkismetComment comment = new AkismetComment
- {
- CommentAuthor = "Test",
- CommentAuthorEmail = "test@example.com",
- CommentAuthorUrl = "http://www.spamwebsite.com",
- Referrer = "https://www.google.com",
- UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36",
- CommentContent = "This is a test ham comment",
- CommentType = AkismentCommentType.ContactForm,
- Permalink = $"{ApiKeyUrl}/contact",
- IsTest = "true",
- BlogCharset = "UTF-8",
- BlogLanguage = "en-US",
- CommentDate = DateTime.UtcNow.ToString("s"),
- CommentPostModified = DateTime.UtcNow.ToString("s"),
- UserRole = "administrator"
- };
- var spamResult = Client.Check(comment);
- spamResult.SpamStatus.ShouldBe(SpamStatus.Ham);
- }
-
[Fact]
public async Task CheckHamCommentAsync()
{
diff --git a/Akismet.Tests/Startup.cs b/Akismet.Tests/Startup.cs
new file mode 100644
index 0000000..ef841fd
--- /dev/null
+++ b/Akismet.Tests/Startup.cs
@@ -0,0 +1,18 @@
+#if NETCORE
+using Akismet.Net;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+
+namespace Akismet.Tests
+{
+ public class Startup
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ string apiKey = Environment.GetEnvironmentVariable("AKISMET_API_KEY").Trim();
+ string blogUrl = Environment.GetEnvironmentVariable("AKISMET_API_KEY_URL").Trim();
+ services.AddAkismet(apiKey, "Akismet Test Application", blogUrl);
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/README.md b/README.md
index 148d1f3..69ebc6c 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ AkismetComment comment = new AkismetComment
HoneypotFieldValue = "blah"
};
-var akismetResult = akismet.Check(comment);
+var akismetResult = await akismet.CheckAsync(comment);
bool isSpam = akismetResult.SpamStatus == SpamStatus.Spam; // Options: Ham, Spam, Unspecified (in the case of an error)
// "invalid" and/or combination of X-akismet-alert-code and X-akismet-alert-msg header values
@@ -56,7 +56,20 @@ foreach (string err in akismetResult.Errors)
### .NET Core/.NET 5+ Usage Modifications
+#### Program.cs / Startup.cs
+
+```charp
+builder.Services.AddAkismet(
+ configuration.ApiKey,
+ configuration.AkismetApplicationName,
+ configuration.BlogUrl);
+```
+
+#### Service Class / Controller
+
```csharp
+public class ContactFormController(AkismetClient akismetClient)
+
string ip = Request.Headers["CF-Connecting-IP"].ToString() ?? _contextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString() ?? "";
if (String.IsNullOrWhiteSpace(ip))
ip = _contextAccessor.HttpContext?.GetServerVariable("REMOTE_HOST") ?? "";
@@ -66,6 +79,7 @@ AkismetComment comment = new AkismetComment
UserAgent = Request.Headers[HeaderNames.UserAgent],
Referrer = Request.Headers[HeaderNames.Referer]
};
+var akismetResult = await akismetClient.CheckAsync(comment)
```
### Notes
@@ -73,3 +87,10 @@ AkismetComment comment = new AkismetComment
If `HoneypotFieldName` and `HoneypotFieldValue` are supplied then the library will add these two values to the request:
`honeypot_field_name=honeypot&honeypot=blah`
+
+#### ⚠️Breaking Changes
+
+Version 4.0 has a breaking change:
+
+- Dropped RestClient in favor of HttpClient directly
+- .NET Core/.NET 5+ now utilize dependency injection