From 5bf2e03af0b21a75dfadd85569b98327d77d7fe8 Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Mon, 31 Aug 2026 23:20:57 +0800 Subject: [PATCH 1/2] fix(http-server-csharp): import JsonNodes for record arrays --- .../src/components/models/model-helpers.ts | 8 ++++++-- .../src/components/models/models.test.tsx | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/http-server-csharp/src/components/models/model-helpers.ts b/packages/http-server-csharp/src/components/models/model-helpers.ts index 094d5189b84..e4550f4bd73 100644 --- a/packages/http-server-csharp/src/components/models/model-helpers.ts +++ b/packages/http-server-csharp/src/components/models/model-helpers.ts @@ -185,9 +185,13 @@ export function isValueType($: ReturnType["$"], type: Type): bool /** Returns true if any property of the model uses Record (mapped to JsonObject). */ export function modelNeedsJsonNodes($: ReturnType["$"], model: Model): boolean { for (const prop of model.properties.values()) { - if (prop.type.kind === "Model" && $.record.is(prop.type)) { + let type = prop.type; + while (type.kind === "Model" && $.array.is(type) && type.indexer?.value) { + type = type.indexer.value; + } + if (type.kind === "Model" && $.record.is(type)) { // Only need JsonNodes for Record (maps to JsonObject) - const valueType = prop.type.indexer?.value; + const valueType = type.indexer?.value; if (valueType?.kind === "Intrinsic" && valueType.name === "unknown") return true; } } diff --git a/packages/http-server-csharp/src/components/models/models.test.tsx b/packages/http-server-csharp/src/components/models/models.test.tsx index 1b117faed47..d26c0cd3153 100644 --- a/packages/http-server-csharp/src/components/models/models.test.tsx +++ b/packages/http-server-csharp/src/components/models/models.test.tsx @@ -8,6 +8,7 @@ import { ClassDeclaration } from "@typespec/emitter-framework/csharp"; import { HttpCanonicalizer } from "@typespec/http-canonicalization"; import { beforeEach, expect, it } from "vitest"; import { resolveServiceTypes } from "../../service-resolution.js"; +import { modelNeedsJsonNodes } from "./model-helpers.js"; let runner: TesterInstance; @@ -130,6 +131,21 @@ it("renders a model with nullable union property", async () => { `); }); +it("detects Record nested in array properties", async () => { + const { JsonObjectArray, StringMapArray } = await runner.compile(t.code` + model ${t.model("JsonObjectArray")} { + items: Record[][]; + } + model ${t.model("StringMapArray")} { + items: Record[]; + } + `); + const tk = $(runner.program); + + expect(modelNeedsJsonNodes(tk, JsonObjectArray)).toBe(true); + expect(modelNeedsJsonNodes(tk, StringMapArray)).toBe(false); +}); + it("does not emit a model class for an @useAuth scheme model", async () => { await runner.compile(` @service From ecc93a041af9604f91daae1faf637725f8963653 Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Tue, 1 Sep 2026 11:03:38 +0800 Subject: [PATCH 2/2] chore: add http server C# change description --- .../http-server-csharp-import-json-nodes-2026-09-01.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .chronus/changes/http-server-csharp-import-json-nodes-2026-09-01.md diff --git a/.chronus/changes/http-server-csharp-import-json-nodes-2026-09-01.md b/.chronus/changes/http-server-csharp-import-json-nodes-2026-09-01.md new file mode 100644 index 00000000000..91a2a10d915 --- /dev/null +++ b/.chronus/changes/http-server-csharp-import-json-nodes-2026-09-01.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/http-server-csharp" +--- + +Import `JsonNode` collection types when generating models containing record arrays.