Skip to content

Commit bef80b6

Browse files
Use an explicit reflection-based converter for enums.
1 parent 4249bfa commit bef80b6

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/ModelContextProtocol.Core/McpJsonUtilities.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using ModelContextProtocol.Protocol;
33
using ModelContextProtocol.Server;
44
using System.Diagnostics.CodeAnalysis;
5+
using System.Reflection;
56
using System.Text.Json;
67
using System.Text.Json.Serialization;
78
using System.Text.Json.Serialization.Metadata;
@@ -34,16 +35,17 @@ public static partial class McpJsonUtilities
3435
/// Creates default options to use for MCP-related serialization.
3536
/// </summary>
3637
/// <returns>The configured options.</returns>
38+
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL3050:RequiresDynamicCode", Justification = "Converter is guarded by IsReflectionEnabledByDefault check.")]
3739
private static JsonSerializerOptions CreateDefaultOptions()
3840
{
3941
// Copy the configuration from the source generated context.
4042
JsonSerializerOptions options = new(JsonContext.Default.Options);
4143

4244
// Chain with all supported types and converters from MEAI
4345
options.TypeInfoResolverChain.Add(AIJsonUtilities.DefaultOptions.TypeInfoResolver!);
44-
foreach (JsonConverter converter in AIJsonUtilities.DefaultOptions.Converters)
46+
if (JsonSerializer.IsReflectionEnabledByDefault)
4547
{
46-
options.Converters.Add(converter);
48+
options.Converters.Add(new UserDefinedJsonStringEnumConverter());
4749
}
4850

4951
options.MakeReadOnly();
@@ -104,6 +106,18 @@ internal static bool IsValidMcpToolSchema(JsonElement element)
104106
return AIJsonUtilities.CreateJsonSchema(returnType, serializerOptions: function.JsonSerializerOptions, inferenceOptions: schemaCreateOptions);
105107
}
106108

109+
110+
// Defines a JsonStringEnumConverter that only applies to enums outside of the current assembly.
111+
// This is to ensure that we're not overriding the CustomizableJsonStringEnumConverter that our
112+
// built-in enums are relying on.
113+
[RequiresDynamicCode("Depends on JsonStringEnumConverter which requires dynamic code.")]
114+
private sealed class UserDefinedJsonStringEnumConverter : JsonConverterFactory
115+
{
116+
private readonly JsonStringEnumConverter _converter = new();
117+
public override bool CanConvert(Type typeToConvert) => _converter.CanConvert(typeToConvert) && typeToConvert.Assembly != Assembly.GetExecutingAssembly();
118+
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) => _converter.CreateConverter(typeToConvert, options);
119+
}
120+
107121
// Keep in sync with CreateDefaultOptions above.
108122
[JsonSourceGenerationOptions(JsonSerializerDefaults.Web,
109123
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,

0 commit comments

Comments
 (0)