From 7275214ceb59f457be439efb974960dd581f4ffc Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 23 Feb 2024 14:05:16 +0100 Subject: [PATCH] Add custom json formatter for `format: date` --- .../v3/DefinitionCompiler.fs | 4 ++++ src/SwaggerProvider.Runtime/RuntimeHelpers.fs | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs b/src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs index a0e980d..93232cb 100644 --- a/src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs +++ b/src/SwaggerProvider.DesignTime/v3/DefinitionCompiler.fs @@ -263,6 +263,10 @@ type DefinitionCompiler(schema: OpenApiDocument, provideNullable) as this = let pField, pProp = generateProperty propName pTy + // + if (schemaObj.Type, schemaObj.Format) = ("string", "date") then + pProp.AddCustomAttribute(RuntimeHelpers.getDateTimeOffsetFullDateConverterAttribute()) + if not <| String.IsNullOrWhiteSpace propSchema.Description then pProp.AddXmlDoc propSchema.Description diff --git a/src/SwaggerProvider.Runtime/RuntimeHelpers.fs b/src/SwaggerProvider.Runtime/RuntimeHelpers.fs index 07867b8..7cefc56 100644 --- a/src/SwaggerProvider.Runtime/RuntimeHelpers.fs +++ b/src/SwaggerProvider.Runtime/RuntimeHelpers.fs @@ -2,6 +2,7 @@ namespace Swagger.Internal open System open System.Net.Http +open System.Text.Json open System.Text.Json.Serialization open System.Threading.Tasks @@ -18,6 +19,19 @@ module MediaTypes = [] let MultipartFormData = "multipart/form-data" +type DateTimeOffsetFullDateConverter() = + + inherit JsonConverter() + + override this.Read(reader: byref, _typ: Type, options: JsonSerializerOptions) = + DateTimeOffset.Parse(reader.GetString()) + + override this.Write(writer: Utf8JsonWriter, value: DateTimeOffset, options: JsonSerializerOptions) = + writer.WriteStringValue( + // full-date: date-fullyear "-" date-month "-" date-mday according to https://datatracker.ietf.org/doc/html/rfc3339#section-5.6 + // this format is required for strings with format 'date' according to https://swagger.io/docs/specification/data-models/data-types/ + value.ToUniversalTime().ToString("yyyy-MM-dd") + ) type AsyncExtensions() = static member cast<'t> asyncOp = @@ -123,6 +137,15 @@ module RuntimeHelpers = member _.NamedArguments = [||] :> Collections.Generic.IList<_> } + let getDateTimeOffsetFullDateConverterAttribute() = + { new Reflection.CustomAttributeData() with + member _.Constructor = typeof.GetConstructor [| typeof |] + + member _.ConstructorArguments = + [| Reflection.CustomAttributeTypedArgument(typeof, typeof) |] :> Collections.Generic.IList<_> + + member _.NamedArguments = [||] :> Collections.Generic.IList<_> } + let toStringContent(valueStr: string) = new StringContent(valueStr, Text.Encoding.UTF8, "application/json")