Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,13 @@ See [SaaS platform payments with subscription billing using Accounts v2](https:/

* [#3069](https://github.com/stripe/stripe-dotnet/pull/3069) Enhance beta version handling in ApiVersion
* `StripeConfiguation.AddBetaVersion` will use the highest version number used for a beta feature instead of throwing an `Exception` on a conflict as it had done previously.


## 48.0.2 - 2025-04-15
* [#3101](https://github.com/stripe/stripe-dotnet/pull/3101) Replace Dictionary with ConcurrentDictionary in SerializablePropertyCache to fix a concurrency related error reported in [#3100](https://github.com/stripe/stripe-dotnet/issues/3100)

## 48.0.1 - 2025-04-14
* [#3090](https://github.com/stripe/stripe-dotnet/pull/3090) Disable Json.NET metadata special handling. Fixes issue [#3068](https://github.com/stripe/stripe-dotnet/issues/3068)

## 48.0.0 - 2025-04-01
* [#3074](https://github.com/stripe/stripe-dotnet/pull/3074) System.Text.Json Serialization Support release to GA
* Add System.Text.Json support for serializing Stripe.net entities and objects for applications running on .NET 6 and above. Now you can pass a Stripe.net object or collection of objects to the System.Text.Json serializer and it will produce the correct JSON string.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ private static List<KeyValuePair<string, object>> FlattenParamsValue(object valu
flatParams = SingleParam(keyPrefix, JsonUtils.SerializeObject(e).Trim('"'));
break;

case bool b:
flatParams = SingleParam(
keyPrefix,
b ? "true" : "false");
break;

default:
flatParams = SingleParam(
keyPrefix,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace Stripe.Infrastructure
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
using System.Text.Json;
Expand All @@ -13,17 +14,17 @@ namespace Stripe.Infrastructure
/// </summary>
internal class SerializablePropertyCache
{
private static Dictionary<Type, JsonConverter> converterCache = new Dictionary<Type, JsonConverter>();
private static Dictionary<Type, List<SerializablePropertyInfo>> propertyCache = new Dictionary<Type, List<SerializablePropertyInfo>>();
private static ConcurrentDictionary<Type, JsonConverter> converterCache = new ConcurrentDictionary<Type, JsonConverter>();
private static ConcurrentDictionary<Type, List<SerializablePropertyInfo>> propertyCache = new ConcurrentDictionary<Type, List<SerializablePropertyInfo>>();

internal static List<SerializablePropertyInfo> GetPropertiesForType(Type type)
{
if (!propertyCache.TryGetValue(type, out var propsToSerialize))
return propertyCache.GetOrAdd(type, (key) =>
{
// Gets the all properties including nonpublic properties
var rawProps = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

propsToSerialize = new List<SerializablePropertyInfo>();
var propsToSerialize = new List<SerializablePropertyInfo>();
foreach (var prop in rawProps)
{
var propertyNameAttribute = prop.GetCustomAttribute(typeof(JsonPropertyNameAttribute), false) as JsonPropertyNameAttribute;
Expand Down Expand Up @@ -55,10 +56,8 @@ internal static List<SerializablePropertyInfo> GetPropertiesForType(Type type)
});
}

propertyCache[type] = propsToSerialize;
}

return propsToSerialize;
return propsToSerialize;
});
}

// Create the various methods stored in SerializablePropertyInfo
Expand Down Expand Up @@ -169,11 +168,10 @@ private static Action<object, object> CreateSetDelegate<T, TValue>(MethodInfo m)
private static JsonConverter<object> GetConverterForType<T, TV>(Type ct)
where T : JsonConverter<TV>
{
if (!converterCache.TryGetValue(ct, out var conv))
var conv = converterCache.GetOrAdd(ct, (key) =>
{
conv = (JsonConverter)Activator.CreateInstance(ct);
converterCache[ct] = conv;
}
return (JsonConverter)Activator.CreateInstance(ct);
});

return new JsonConverterAdapter<T, TV>((T)conv);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,15 @@ public void CreateQueryString()
{
Bool = false,
},
Want = "bool=False",
Want = "bool=false",
},
new QueryStringTestCase
{
Data = new TestOptions
{
Bool = true,
},
Want = "bool=True",
Want = "bool=true",
},

// DateRangeOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public void SerializeObjectProperly()
OffSession = true,
};

Assert.Equal("off_session=True", ContentEncoder.CreateQueryString(options_bool));
Assert.Equal("off_session=true", ContentEncoder.CreateQueryString(options_bool));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public void SerializeObjectProperly()
OffSession = true,
};

Assert.Equal("off_session=True", ContentEncoder.CreateQueryString(options_bool));
Assert.Equal("off_session=true", ContentEncoder.CreateQueryString(options_bool));
}
}
}
Loading