Skip to content

VectorIndexPath: Adds System.Text.Json attribute parity for vector-index DOM types #5922

@ananth7592

Description

@ananth7592

Summary

VectorIndexPath, VectorIndexType, QuantizerType, and VectorIndexShardKey carry only Newtonsoft attributes ([JsonProperty], [JsonIgnore], [JsonConverter(typeof(StringEnumConverter))], [EnumMember(Value = "flat")], etc.). The SDK's internal write path for ContainerProperties is hard-routed through Newtonsoft via CosmosSerializerCore.IsInputTypeInternal, so this is correct for first-party use.

However, any customer code that re-serializes these public types with System.Text.Json — directly, or via a DTO mapped 1:1 onto our public shape — gets a wire body the service rejects:

  • [JsonIgnore] on the public IndexingSearchListSize is not honored by STJ → emits "IndexingSearchListSize": 0.
  • [JsonProperty(... NullValueHandling.Ignore)] on the private backing field is not seen → never emits "indexingSearchListSize" from the right source.
  • [JsonConverter(typeof(StringEnumConverter))] + [EnumMember(Value = "flat")] on Type is not honored → emits "Type": 0 instead of "flat".
  • [JsonProperty("path")] is not honored → emits "Path" (PascalCase).

This came up in an internal customer (Intune) repro where they round-trip indexing policies through their own STJ-serialized DTOs as part of a config-management pipeline. They've already worked around the enum casing with [EnumMember] on their own types but cannot work around the IndexingSearchListSize emission without changing every DTO property's type and ignore-condition.

Proposed change

Add parallel STJ attributes to the vector-index DOM types so they round-trip cleanly under either serializer. This is the same pattern adopted in PR #4618 for ChangeFeedItem / ChangeFeedMetadata:

// Example: VectorIndexPath.Type
[Newtonsoft.Json.JsonProperty(PropertyName = "type")]
[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
[System.Text.Json.Serialization.JsonPropertyName("type")]
[System.Text.Json.Serialization.JsonConverter(typeof(EnumMemberStringEnumConverter<VectorIndexType>))]
public VectorIndexType Type { get; set; }

Scope:

  • VectorIndexPath — all properties (Path, Type, Dimensions, DistanceFunction, IndexingSearchListSize, QuantizationByteSize, VectorIndexShardKey)
  • VectorIndexType, QuantizerType, DistanceFunction — string-enum converter that honors [EnumMember]
  • VectorIndexShardKey

The public IndexingSearchListSize / QuantizationByteSize need [System.Text.Json.Serialization.JsonIgnore] so STJ doesn't double-emit them; the private backing fields need a matching [JsonPropertyName] + [JsonInclude] (or be promoted to internal-public bridges that STJ can see).

Tests to add

For each affected type, two repro fixtures:

  1. Serialize via Newtonsoft → assert exact wire shape (existing behavior unchanged).
  2. Serialize via STJ (default options + camelCase policy) → assert the same wire shape.

Why now

Customers are increasingly building config / IaC pipelines on top of System.Text.Json (AOT-friendly, no Newtonsoft dependency). The vector-index types are new enough that the inconsistency hasn't compounded yet — fixing it now is much cheaper than after broader adoption.

This is a focused subset of the broader STJ migration tracked across the AOT work; it doesn't require flipping the internal serializer, just publishing the dual attributes on the user-visible types.

Precedent

PR #4618ChangeFeedItem / ChangeFeedMetadata dual-attribute work, same pattern.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions