F2X
**Is your feature request related to a problem? Please describe.** A custom `format` on a string schema silently degrades the generated property to `string`, with no warning and no way to configure the mapping. That makes a custom format unusable in any document shared with an NSwag consumer, even when the format is meaningful to every other generator reading the same file. `CSharpTypeResolver.ResolveString` ([NJsonSchema, master](https://github.com/RicoSuter/NJsonSchema/blob/master/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs)) is a closed if-chain over `JsonFormatStrings`, ending in a catch-all: ```csharp if (schema.Format == JsonFormatStrings.Date) { return Settings.DateType …; } if (schema.Format == JsonFormatStrings.DateTime) { return Settings.DateTimeType …; } if (schema.Format == JsonFormatStrings.Time) { return Settings.TimeType …; } // … Duration, TimeSpan, Uri, Guid/Uuid, Base64/Byte … return "string" + nullableReferenceType; // ← any other format ``` `CSharpGeneratorSettings` exposes `DateType`, `DateTimeType`, `TimeType`, `TimeSpanType`, `NumberType`… — these let you change *which* type a **known** format maps to, but there is no way to add a key. `TypeScriptTypeResolver.ResolveString` has the same shape, so the limitation is symmetric. **The concrete case.** OpenAPI describes a C# `DateTime` and a `DateTimeOffset` with the same `format: "date-time"`, though they do not carry the same thing on the wire: | C# | serialized | |---|---| | `DateTime` (`Kind = Unspecified`) | `2024-01-31T00:00:00` | | `DateTimeOffset` | `2024-01-31T00:00:00+01:00` | OpenAPI does not stand in the way of separating them: `format` is *"an open string-valued property, and can have any value"*, so `format: "date-time-offset"` is a legal document. But measured on a real service (NSwag 14.7.0, `dateTimeType: System.DateTimeOffset`, one document generating both a TypeScript and a C# client): | Document carries | C# client output | |---|---| | `format: "date-time"` | `System.DateTimeOffset` | | `format: "date-time-offset"` | **`string`** — 45 properties degraded | So the moment a producer emits the more precise format, every NSwag-generated .NET client loses its typing — silently, at build time, with no diagnostic. The failure is invisible until someone notices the client's properties became strings. Worth noting the same collapse affects the generated C# client itself: with `dateTimeType: System.DateTimeOffset`, the 19 offset-less `DateTime` properties and the 45 `DateTimeOffset` ones all land on `System.DateTimeOffset`, so the client cannot distinguish them either. There is currently no way to express that difference in the document without breaking the client entirely. **Describe the solution you'd like** A configurable format → type map, so an unknown format is a *decision* rather than a silent fallback. Something like: ```jsonc // nswag.json → codeGenerators.openApiToCSharpClient "customTypeFormats": { "date-time-offset": "System.DateTimeOffset", "date-time-utc": "System.DateTime" } ``` consulted in `ResolveString` before the `return "string"` fallback. Unconfigured formats keep today's behaviour exactly, so this is additive and breaks nothing. Two smaller variants, if a new setting is unwelcome: 1. **Make the fallback observable** — log a warning when a non-empty `format` on a `string` schema matches no known format. That alone would have surfaced the problem at generation time instead of in review. 2. **Make the resolution overridable** — `ResolveString` is `private`; `Resolve` is `public override`, so a subclass can technically intercept, but there is no documented way to inject a custom `CSharpTypeResolver` through `nswag.json` or the CLI. A protected virtual hook plus a settings entry point would let consumers solve this themselves. **Describe alternatives you've considered** - **Keeping the standard `format` and carrying the distinction in a vendor extension** — what we ship today. `format: "date-time"` stays, and an `x-temporal-format: "date-time-offset"` rides alongside it; NSwag ignores unknown `x-` extensions and keeps emitting `System.DateTimeOffset`, while the other generator reads the extension. It works, and `JsonSchema.ExtensionData` means the information is already parsed and available should NSwag ever want to read it — but it means every producer has to know NSwag specifically, and pick a non-standard carrier for something `format` was designed to express. - **Carrying it in `title`** — worse: `title` is a display annotation, so the value surfaces as the property label in Swagger UI / Redoc. - **Post-processing the generated client** — rejected; the file is regenerated on every build. - **A `x-nswag-type` style per-schema override** — would solve it, but couples the document to one generator; a settings-side map keeps the document neutral. **Additional context** Happy to open a PR if the direction is agreeable — the change in `ResolveString` is small, and the symmetric one in `TypeScriptTypeResolver` would keep the two generators consistent. Please say which of the three shapes above you would accept before I write it. Versions: NSwag 14.7.0 (`NSwag.ApiDescription.Client`, MSBuild target, .NET 10), document generated by Swashbuckle from an ASP.NET Core API.