Visual Studio 將任何本機的 Draft 2020-12 JSON Schema 檔案視為一份合約,藉此為每個透過結構描述目錄或 `$schema` 參考連接到它的 JSON 文件提供 IntelliSense、自動完成與內嵌驗證。若要在 Visual Studio 中建立 JSON Schema,最可靠的工作流程是:先透過瀏覽器型工具(例如 JSON Schema Generator)從一個嚴格的 JSON 範例產生結構描述,將產生的 `.json` 檔案儲存到專案目錄內,然後透過 Tools > Options > JSON > Schema 讓 IDE 指向該檔案,或在需要用它驗證的文件中加入 `$schema` 屬性。產生器會遞迴走訪該範例、明確宣告 Draft 2020-12 dialect,並在證據需要時產出包含 `properties`、`required`、`items`、可空值處理以及 `anyOf` 分支的決定性文字,因此你所提交的檔案在結構上是有根據的,而非手動輸入的。本指南將逐步帶領你走完這個端對端流程、說明產生器刻意省略的部分,以及在將結構描述送入版本控制之前你應該執行的驗證。

What Visual Studio Actually Needs From a JSON Schema File
Visual Studio reads JSON Schemas as ordinary JSON documents that follow a documented dialect. When you register a schema through the IDE's JSON > Schema catalog under Tools > Options, the language service parses the file, indexes its `properties`, `required`, `items`, and type unions, and uses that index to offer inline completions and error squiggles inside every JSON document that resolves to the schema. The schema can live on disk at an absolute path, on disk at a path relative to the open solution, or on a remote URL referenced through the `$schema` keyword at the top of a JSON file.
The dialect matters: Visual Studio's built-in JSON support understands the published JSON Schema specifications, and the JSON Schema Generator emits documents that declare the Draft 2020-12 URI explicitly so the editor recognizes the keyword vocabulary. That declaration, combined with stable `properties` ordering and a deterministic `required` array, is what makes the generated schema usable for IntelliSense instead of being parsed and ignored. The shape Visual Studio needs is the shape any Draft 2020-12 validator needs: a top-level object that names its dialect, declares `type` where appropriate, and uses the standard validation keywords without inventing constraints the sample cannot prove.
Why Generate the Schema From a Sample in Your Browser
Hand-writing a JSON Schema from scratch inside Visual Studio is possible, but it forces you to anticipate every property, every nullable field, and every mixed-type array before you have seen real payloads. For a contract that already exists as concrete JSON examples, sample-driven inference is faster and harder to get structurally wrong. The JSON Schema Generator reads one strict JSON value in the current browser tab, walks the structure recursively, and emits a Draft 2020-12 document with `properties`, `required`, `items`, `anyOf`, and explicit nullable handling. Nothing leaves your machine: parsing, inference, and text generation all run locally, so you can paste real API payloads without worrying about telemetry or uploads.
Browser generation also gives you a reviewable diff. Every time you regenerate from the same sample, the output is byte-for-byte identical, which means the schema can live under source control without churn. If a teammate later changes the sample, the regenerated diff shows exactly which keywords the schema has gained or lost, instead of hiding the change inside a hand-edited document.
Generate the Draft 2020-12 JSON Schema Step by Step
- Open the JSON Schema Generator in a new browser tab and keep your Visual Studio project open beside it so you can move text between the two without losing context.
- Pick the most representative strict JSON value your project already produces or consumes. A saved Postman response, a captured payload from a debugger, or a `.json` resource from the project itself all work. Validate the candidate first with the JSON Validator if there is any chance of comments, trailing commas, or JavaScript literals, because the generator rejects anything that is not strict JSON.
- Paste the sample into the generator's input area. Optionally type a short schema title such as `OrderResponse` or `AppSettings` so the generated document carries a human-readable name. Do not paste business descriptions, version notes, or identifier hints — the generator ignores anything that is not parseable JSON.
- Click Generate and wait for the output to render. Read the produced schema top-down and confirm that `properties` lists every key you expect, that `required` contains exactly the keys you saw in every sample object, and that nullable fields appear as a `type` array containing both `null` and the underlying type rather than as a single bare type.
- Inspect the array sections. Arrays whose elements were all the same shape will show a single `items` schema; arrays whose elements were mixed will show an `anyOf` array of branches in a deterministic order. Empty arrays will show an empty `items` schema, which is the conservative signal that the generator refuses to invent a constraint it cannot justify.
- Copy the generated schema text, then return to Visual Studio. Create a new file inside the project tree with the `.json` extension, paste the schema, and save it with a stable name such as `schemas/order-response.schema.json`. Commit it to source control so the rest of the team sees the same starting point.
- Run a final mental check: confirm there is no `additionalProperties` keyword in the output. Its absence is intentional. The generator refuses to mark the object as closed because a single sample cannot prove that unobserved keys are forbidden.
Place the Schema File in Your Visual Studio Project
Drop the generated `.json` file into a folder your team treats as the schema catalog, commonly `schemas/`, `contracts/`, or `json/`. Inside Visual Studio, open Tools > Options and locate the JSON language settings; the IDE exposes a schema catalog where you can add an absolute path, a relative path inside the solution, or a URL. For local-first projects, a relative path inside the solution is the most portable choice because it travels with the repository. For per-document wiring, add a top-level `$schema` property inside each JSON file that points at the generated schema, either by relative path or by an HTTP URL hosted on your team's schema registry.
If you keep the schema inside the same project, IntelliSense activates automatically as soon as Visual Studio parses the file and indexes its `properties`. If the IDE does not pick the schema up immediately, close and reopen the JSON document, or restart Visual Studio so the language service rescans the schema catalog. For very large solutions, prefer a dedicated schema folder over scattering schema files next to the documents that consume them, because the catalog UI is easier to manage when every schema lives in one known location.
What the Generator Outputs and What It Deliberately Omits
The generator maps observed values directly to Draft 2020-12 keywords. The following table summarizes how each observed JSON construct becomes a schema construct in the output file.
| Observed JSON value | Generated schema construct |
|---|---|
| JSON string | `"type": "string"` |
| Safe integer inside the JSON.parse range | `"type": "integer"` |
| Other numeric values such as floats and large integers parsed by JavaScript | `"type": "number"` |
| Boolean true or false | `"type": "boolean"` |
| JSON null | `"type": "null"` |
| Array with observed elements | `"type": "array"` with `items` inferred recursively from every element; mixed compatible numbers widen to `number`; incompatible mixes become deterministic `anyOf` branches |
| Empty array | `"type": "array"` with an empty `items` schema |
| Object | `"type": "object"` with `properties` and a `required` array listing every key present in every merged object |
The generator never infers the following keywords from a sample: `format`, `pattern`, `enum`, `const`, `minimum`, `maximum`, `multipleOf`, `minLength`, `maxLength`, `uniqueItems`, `description`, `default`, `examples`, `deprecated`, `readOnly`, `writeOnly`, `contentEncoding`, `$ref`, `$anchor`, `$id`, `if`/`then`/`else`, and `unevaluatedProperties`. A spelling or a small sample is insufficient evidence for any of those semantic constraints, so the generator leaves them out and expects you to add them from authoritative requirements. The Draft 2020-12 core specification documents each keyword so you can decide which ones your contract truly needs.
Property names are preserved exactly, including punctuation and prototype-shaped spellings such as `__proto__`, `constructor`, or keys with embedded dots. A property observed in every merged object becomes required; a property missing from at least one object is left out of `required`. Null combined with a directly typed schema adds `null` to the `type` array while keeping the existing `properties` or `items`; more complex combinations become `anyOf` branches in a deterministic order so the same input always produces stable text.
Test the Copied Schema With a Production Validator
Before you commit the generated file, run it through the same Draft 2020-12-capable validator your runtime uses. The generator does not run a validator itself, so this step is yours. Feed it at least one positive instance (a JSON document that should pass) and at least one negative instance (a JSON document that should fail on a specific keyword). Confirm the failure points at the keyword you actually wrote, not at a default the IDE or runtime substituted because it did not understand the dialect.
For per-document validation inside Visual Studio, place a `$schema` reference at the top of each JSON file that should be validated. For project-wide IntelliSense, register the schema through the JSON > Schema catalog under Tools > Options. Either wiring lets the editor surface errors as you type, which is the practical payoff of having a Draft 2020-12 schema checked into the project in the first place.
Respect the Generator's Hard Limits
The generator enforces four hard ceilings and refuses to produce a partial schema when any of them is crossed. Inputs larger than 500,000 characters are rejected, samples with more than 50,000 individual JSON values are rejected, structures nested deeper than 40 levels are rejected, and outputs longer than 1,000,000 characters are rejected. If your sample trips one of these limits, narrow the input by trimming unrelated branches or split the schema into several smaller documents and reference them with `$ref` from a top-level schema. The limits exist so a malformed or pathological input never yields a silently truncated schema that later fails to validate.
Strict JSON is required at the input. Comments, trailing commas, `NaN`, `Infinity`, `undefined`, BigInt literals, and JavaScript object literals all fail the parser before inference begins. JavaScript parses each sample number before inference, which means only safe integers become `"integer"` and any larger rounded value is emitted as `"number"` to avoid a false exactness claim. If your contract carries precision-sensitive decimals or opaque identifiers, keep them as strings and add application-level validation rather than relying on `format` keywords added by the generator, because the generator never produces them.
Related reading: JSON to CSV in Bulk: Limits and a Local Workflow.
Related reading: Convert JSON to Excel Without Power Query: A Browser Workflow.