1
0
mirror of https://github.com/bitwarden/server synced 2026-01-15 15:03:34 +00:00
Files
server/src/Core/Utilities/EnumMemberJsonConverter.cs
Alex Morask cfa8d4a165 [PM-29604] [PM-29605] [PM-29606] Support premium subscription page redesign (#6821)
* feat(get-subscription): Add EnumMemberJsonConverter

* feat(get-subscription): Add BitwardenDiscount model

* feat(get-subscription): Add Cart model

* feat(get-subscription): Add Storage model

* feat(get-subscription): Add BitwardenSubscription model

* feat(get-subscription): Add DiscountExtensions

* feat(get-subscription): Add error code to StripeConstants

* feat(get-subscription): Add GetBitwardenSubscriptionQuery

* feat(get-subscription): Expose GET /account/billing/vnext/subscription

* feat(reinstate-subscription): Add ReinstateSubscriptionCommand

* feat(reinstate-subscription): Expose POST /account/billing/vnext/subscription/reinstate

* feat(pay-with-paypal-immediately): Add SubscriberId union

* feat(pay-with-paypal-immediately): Add BraintreeService with PayInvoice method

* feat(pay-with-paypal-immediately): Pay PayPal invoice immediately when starting premium subscription

* feat(pay-with-paypal-immediately): Pay invoice with Braintree on invoice.created for subscription cycles only

* fix(update-storage): Always invoice for premium storage update

* fix(update-storage): Move endpoint to subscription path

* docs: Note FF removal POIs

* (format): Run dotnet format
2026-01-12 10:45:41 -06:00

53 lines
2.0 KiB
C#

using System.Reflection;
using System.Runtime.Serialization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Bit.Core.Utilities;
/// <summary>
/// A custom JSON converter for enum types that respects the <see cref="EnumMemberAttribute"/> when serializing and deserializing.
/// </summary>
/// <typeparam name="T">The enum type to convert. Must be a struct and implement Enum.</typeparam>
/// <remarks>
/// This converter builds lookup dictionaries at initialization to efficiently map between enum values and their
/// string representations. If an enum value has an <see cref="EnumMemberAttribute"/>, the attribute's Value
/// property is used as the JSON string; otherwise, the enum's ToString() value is used.
/// </remarks>
public class EnumMemberJsonConverter<T> : JsonConverter<T> where T : struct, Enum
{
private readonly Dictionary<T, string> _enumToString = new();
private readonly Dictionary<string, T> _stringToEnum = new();
public EnumMemberJsonConverter()
{
var type = typeof(T);
var values = Enum.GetValues<T>();
foreach (var value in values)
{
var fieldInfo = type.GetField(value.ToString());
var attribute = fieldInfo?.GetCustomAttribute<EnumMemberAttribute>();
var stringValue = attribute?.Value ?? value.ToString();
_enumToString[value] = stringValue;
_stringToEnum[stringValue] = value;
}
}
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var stringValue = reader.GetString();
if (!string.IsNullOrEmpty(stringValue) && _stringToEnum.TryGetValue(stringValue, out var enumValue))
{
return enumValue;
}
throw new JsonException($"Unable to convert '{stringValue}' to {typeof(T).Name}");
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
=> writer.WriteStringValue(_enumToString[value]);
}