JamesNK/Newtonsoft.Json · error · InvalidOperationException
Could not resolve type '{0}'. You may need to add a referenc
Error message
Could not resolve type '{0}'. You may need to add a reference to Microsoft.CSharp.dll to work with dynamic types. What it means
BinderWrapper.Init (DynamicUtils.cs:66-84) resolves the Microsoft.CSharp.RuntimeBinder types by reflection (Type.GetType of the fully-qualified BinderTypeName) to support deserializing into `dynamic`. If Microsoft.CSharp.dll is not loaded/referenced, Type.GetType returns null and it throws InvalidOperationException at DynamicUtils.cs:73, advising to add a reference to Microsoft.CSharp.dll.
Source
Thrown at Src/Newtonsoft.Json/Utilities/DynamicUtils.cs:73
private const string CSharpArgumentInfoFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, " + CSharpAssemblyName;
private const string CSharpBinderFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, " + CSharpAssemblyName;
private static object? _getCSharpArgumentInfoArray;
private static object? _setCSharpArgumentInfoArray;
private static MethodCall<object?, object?>? _getMemberCall;
private static MethodCall<object?, object?>? _setMemberCall;
private static bool _init;
[RequiresUnreferencedCode(MiscellaneousUtils.TrimWarning)]
[RequiresDynamicCode(MiscellaneousUtils.AotWarning)]
private static void Init()
{
if (!_init)
{
Type? binderType = Type.GetType(BinderTypeName, false);
if (binderType == null)
{
throw new InvalidOperationException("Could not resolve type '{0}'. You may need to add a reference to Microsoft.CSharp.dll to work with dynamic types.".FormatWith(CultureInfo.InvariantCulture, BinderTypeName));
}
// None
_getCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0);
// None, Constant | UseCompileTimeType
_setCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0, 3);
CreateMemberCalls();
_init = true;
}
}
[RequiresDynamicCode(MiscellaneousUtils.AotWarning)]
private static object CreateSharpArgumentInfoArray(params int[] values)
{
Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName, true)!;
Type csharpArgumentInfoFlags = Type.GetType(CSharpArgumentInfoFlagsTypeName, true)!;
View on GitHub (pinned to 4f73e74372)
Solutions
- Add the Microsoft.CSharp NuGet package (or the assembly reference) to the project.
- Avoid deserializing to dynamic; deserialize to a concrete type or to JObject/JToken instead.
- If trimming, ensure Microsoft.CSharp is not trimmed (add a trim root / TrimmerRootDescriptor).
- On frameworks with HAVE_REFLECTION_BINDER defined, ensure the Binder type is reachable.
Example fix
// before dynamic d = JsonConvert.DeserializeObject(json); // throws if Microsoft.CSharp missing // after: add the Microsoft.CSharp package, or JObject d = JsonConvert.DeserializeObject<JObject>(json);
Defensive patterns
Strategy: validation
Validate before calling
// Detect the missing binder before deserializing to dynamic.
static bool DynamicBinderAvailable() {
try { return System.AppDomain.CurrentDomain.GetAssemblies().Any(a => a.GetName().Name == "Microsoft.CSharp"); }
catch { return false; }
} Type guard
static bool SupportsDynamic() => Type.GetType("Microsoft.CSharp.RuntimeBinder.Binder, Microsoft.CSharp") != null; Try / catch
try { dynamic d = JsonConvert.DeserializeObject(json); } catch (InvalidOperationException ex) when (ex.Message.Contains("Microsoft.CSharp.dll")) { var d = JsonConvert.DeserializeObject<JObject>(json); } Prevention
- Add the Microsoft.CSharp package when deserializing to dynamic.
- Prefer JObject/JToken over dynamic for portability.
- Prevent trimming of Microsoft.CSharp in AOT scenarios.
When it happens
Trigger: Deserializing JSON into `dynamic`/ExpandoObject (or otherwise exercising the dynamic binder path) on a runtime/framework where the Microsoft.CSharp assembly is absent — only reached when HAVE_REFLECTION_BINDER is not defined.
Common situations: .NET Core / .NET 5+ projects without the Microsoft.CSharp NuGet package; trimmed/AOT apps where the binder was removed; deserializing to dynamic in environments that ship a minimal BCL.
Related errors
- Newtonsoft.Json support for dynamic is not compatible with t
- Invalid date time handling value.
- Enum name '{0}' already exists on enum '{1}'.
- Enum type {0} is not a set of flags.
- Integer string '{0}' is not allowed.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/42b738ac511efc3a.
Report an issue: GitHub.