JamesNK/Newtonsoft.Json · error · JsonSerializationException

Expected JSON property

Error message

Expected JSON property '{0}'.

What it means

Thrown by EntityKeyMemberConverter.ReadAndAssertProperty when the next JSON token is not the expected property name ('Key', 'Type', or 'Value' by default, or the resolver-renamed equivalents). EntityKeyMemberConverter serializes a System.Data.EntityKeyMember as an object with those three properties in order; on read it asserts each in sequence and throws if the stream deviates.

Solutions

  1. Ensure the JSON object contains all three properties Key, Type, and Value with the exact casing expected (apply a DefaultContractResolver with the same naming policy on both ends).
  2. If the producer uses camelCase, configure the serializer with CamelCasePropertyNamesContractResolver so 'key'/'type'/'value' match.
  3. If you do not actually need EntityKeyMember serialization, remove the converter or avoid round-tripping EntityKeyMember over JSON.
  4. Validate the payload schema before deserializing.

Example fix

// before: producer emits camelCase, default reader expects PascalCase
// { "key": "Id", "type": "System.Int32", "value": 7 }
var key = JsonConvert.DeserializeObject<EntityKeyMember>(json);

// after: match naming on both sides
var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var key = JsonConvert.DeserializeObject<EntityKeyMember>(json, settings);
Defensive patterns

Strategy: validation

Validate before calling

// Validate the JSON shape before deserializing EntityKeyMember
var jo = JObject.Parse(json);
foreach (var prop in new[] { "Key", "Type", "Value" })
{
    var name = resolver.GetResolvedPropertyName(prop);
    if (jo.Property(name, StringComparison.OrdinalIgnoreCase) == null)
        throw new InvalidDataException($"Missing expected property '{prop}'");
}

Type guard

static bool HasEntityKeyShape(JObject o) =>
    o.ContainsKey("Key", StringComparison.OrdinalIgnoreCase)
    && o.ContainsKey("Type", StringComparison.OrdinalIgnoreCase)
    && o.ContainsKey("Value", StringComparison.OrdinalIgnoreCase);

Try / catch

try { var k = serializer.Deserialize<EntityKeyMember>(reader); }
catch (JsonSerializationException ex) when (ex.Message.Contains("Expected JSON property"))
{
    throw new InvalidDataException("EntityKeyMember JSON is missing a required property", ex);
}

Prevention

When it happens

Trigger: Deserializing JSON into an EntityKeyMember when the JSON object is missing a required property or has them in the wrong order/naming. For example JSON with {"key":...} when a camelCase resolver is not configured, or a payload that omits 'Type' or 'Value'. Only available when HAVE_ENTITY_FRAMEWORK is defined.

Common situations: Receiving EntityKeyMember JSON from a source that renamed properties (camelCase vs PascalCase) without a matching contract resolver. Hand-editing the JSON and dropping a field. A producer that omits the Type field because the value was null. Version skew where the producer writes a different shape.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/66468d036c80bd79. Report an issue: GitHub.

Appendix: source

Thrown at Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs:108

                {
                    writer.WriteValue(keyValue);
                }
            }
            else
            {
                writer.WriteNull();
            }

            writer.WriteEndObject();
        }

        private static void ReadAndAssertProperty(JsonReader reader, string propertyName)
        {
            reader.ReadAndAssert();

            if (reader.TokenType != JsonToken.PropertyName || !string.Equals(reader.Value?.ToString(), propertyName, StringComparison.OrdinalIgnoreCase))
            {
                throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName));
            }
        }

        /// <summary>
        /// Reads the JSON representation of the object.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="existingValue">The existing value of object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        /// <returns>The object value.</returns>
        public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
        {
            EnsureReflectionObject(objectType);
            MiscellaneousUtils.Assert(_reflectionObject != null);

            object entityKeyMember = _reflectionObject.Creator!();

View on GitHub (pinned to 4f73e74372)