From c8ed15beb0fbe8801e051ffa12240798ede5a5f8 Mon Sep 17 00:00:00 2001 From: Michael Broshi Date: Tue, 24 Mar 2026 16:18:55 -0400 Subject: [PATCH] Prep for batch jobs --- .../NewtonsoftStringEnumConverter.cs | 35 ++++++++++++++ .../STJStringEnumConverterFactory.cs | 46 +++++++++++++++++++ .../UpcomingInvoiceSubscriptionResumeAt.cs | 3 ++ .../SubscriptionBillingCycleAnchor.cs | 3 ++ src/Stripe.net/Services/_base/StringEnum.cs | 6 +-- 5 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 src/Stripe.net/Infrastructure/JsonConverters/NewtonsoftStringEnumConverter.cs create mode 100644 src/Stripe.net/Infrastructure/JsonConverters/STJStringEnumConverterFactory.cs diff --git a/src/Stripe.net/Infrastructure/JsonConverters/NewtonsoftStringEnumConverter.cs b/src/Stripe.net/Infrastructure/JsonConverters/NewtonsoftStringEnumConverter.cs new file mode 100644 index 0000000000..12b0b42445 --- /dev/null +++ b/src/Stripe.net/Infrastructure/JsonConverters/NewtonsoftStringEnumConverter.cs @@ -0,0 +1,35 @@ +namespace Stripe.Infrastructure +{ + using System; + using Newtonsoft.Json; + + /// + /// Newtonsoft converter that serializes any + /// subclass as its string. + /// + internal class NewtonsoftStringEnumConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return typeof(StringEnum).IsAssignableFrom(objectType); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + } + else + { + writer.WriteValue(((StringEnum)value).Value); + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotSupportedException( + $"Deserialization of {objectType.Name} (StringEnum) is not supported."); + } + } +} diff --git a/src/Stripe.net/Infrastructure/JsonConverters/STJStringEnumConverterFactory.cs b/src/Stripe.net/Infrastructure/JsonConverters/STJStringEnumConverterFactory.cs new file mode 100644 index 0000000000..ddfe2dc88f --- /dev/null +++ b/src/Stripe.net/Infrastructure/JsonConverters/STJStringEnumConverterFactory.cs @@ -0,0 +1,46 @@ +namespace Stripe.Infrastructure +{ + using System; + using System.Text.Json; + using System.Text.Json.Serialization; + + /// + /// STJ converter factory that serializes any + /// subclass as its string. + /// + internal class STJStringEnumConverterFactory : JsonConverterFactory + { + public override bool CanConvert(Type typeToConvert) + { + return typeof(StringEnum).IsAssignableFrom(typeToConvert); + } + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + return (JsonConverter)Activator.CreateInstance( + typeof(STJStringEnumConverterInner<>).MakeGenericType(typeToConvert)); + } + + private class STJStringEnumConverterInner : JsonConverter + where T : StringEnum + { + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new NotSupportedException( + $"Deserialization of {typeToConvert.Name} (StringEnum) is not supported."); + } + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + if (value == null) + { + writer.WriteNullValue(); + } + else + { + writer.WriteStringValue(value.Value); + } + } + } + } +} diff --git a/src/Stripe.net/Services/Invoices/UpcomingInvoiceSubscriptionResumeAt.cs b/src/Stripe.net/Services/Invoices/UpcomingInvoiceSubscriptionResumeAt.cs index b2168d706b..2e7c83935b 100644 --- a/src/Stripe.net/Services/Invoices/UpcomingInvoiceSubscriptionResumeAt.cs +++ b/src/Stripe.net/Services/Invoices/UpcomingInvoiceSubscriptionResumeAt.cs @@ -1,5 +1,8 @@ namespace Stripe { + using STJS = System.Text.Json.Serialization; + + [STJS.JsonConverter(typeof(Infrastructure.STJStringEnumConverterFactory))] public class UpcomingInvoiceSubscriptionResumeAt : StringEnum { /// When viewing an upcoming invoice for a subscription, simulates it resuming to the current time. diff --git a/src/Stripe.net/Services/Subscriptions/SubscriptionBillingCycleAnchor.cs b/src/Stripe.net/Services/Subscriptions/SubscriptionBillingCycleAnchor.cs index 022dfed7ff..e9a8eaf9d2 100644 --- a/src/Stripe.net/Services/Subscriptions/SubscriptionBillingCycleAnchor.cs +++ b/src/Stripe.net/Services/Subscriptions/SubscriptionBillingCycleAnchor.cs @@ -1,5 +1,8 @@ namespace Stripe { + using STJS = System.Text.Json.Serialization; + + [STJS.JsonConverter(typeof(Infrastructure.STJStringEnumConverterFactory))] public class SubscriptionBillingCycleAnchor : StringEnum { /// Resets the subscription's billing cycle anchor to the current time. diff --git a/src/Stripe.net/Services/_base/StringEnum.cs b/src/Stripe.net/Services/_base/StringEnum.cs index 71c43a40a7..f9a8a76f8e 100644 --- a/src/Stripe.net/Services/_base/StringEnum.cs +++ b/src/Stripe.net/Services/_base/StringEnum.cs @@ -1,7 +1,5 @@ namespace Stripe { - using System.Text.Json.Serialization; - /// /// Abstract base class for string enum parameters. /// @@ -25,6 +23,8 @@ namespace Stripe /// } /// /// + [Newtonsoft.Json.JsonConverter(typeof(Infrastructure.NewtonsoftStringEnumConverter))] + [NoSystemTextJsonAttributesNeeded("STJ converter is on each concrete subclass because STJ does not inherit converter attributes from base classes.")] public abstract class StringEnum { /// Initializes a new instance of the class. @@ -36,7 +36,7 @@ protected StringEnum(string value) /// Gets or sets the serialized value. /// The serialized value. - [JsonPropertyName("Value")] + [System.Text.Json.Serialization.JsonPropertyName("Value")] public string Value { get; protected set; } /// Returns the serialized value.