Fixes `System.InvalidOperationException: This JsonSerializerOptions instance is read-only or has already been used in serialization or deserialization` by xperiandri · Pull Request #480 · fsprojects/FSharp.Data.GraphQL · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish_release.yml
8 changes: 4 additions & 4 deletions Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<SystemVersion>7.0.*</SystemVersion>
<MicrosoftExtensionsVersion>7.0.*</MicrosoftExtensionsVersion>
<AspNetCoreVersion>7.0.*</AspNetCoreVersion>
<FsToolkitVersion>4.9.*</FsToolkitVersion>
<XUnitVersion>2.6.6</XUnitVersion>
<FsToolkitVersion>4.15.*</FsToolkitVersion>
<XUnitVersion>2.8.1</XUnitVersion>
<FAKEVersion>6.*</FAKEVersion>
</PropertyGroup>
<ItemGroup Label="Common">
Expand Down Expand Up @@ -51,7 +51,7 @@
<ItemGroup Label="Test platform">
<PackageReference Update="BenchmarkDotNet" Version="0.13.*" />
<PackageReference Update="BenchmarkDotNet.Annotations" Version="0.*" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Update="Microsoft.TestPlatform.TestHost" Version="17.7.*" />
<PackageReference Update="Microsoft.TestPlatform.ObjectModel" Version="17.7.*" />
<PackageReference Update="xunit" Version="$(XUnitVersion)" />
Expand All @@ -62,7 +62,7 @@
<PackageReference Update="xunit.extensibility.execution" Version="$(XUnitVersion)" />
<PackageReference Update="xunit.runner.console" Version="$(XUnitVersion)" />
<PackageReference Update="xunit.runner.utility" Version="$(XUnitVersion)" />
<PackageReference Update="xunit.runner.visualstudio" Version="2.5.6" />
<PackageReference Update="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
</ItemGroup>
<ItemGroup Label="Tests and Samples">
<PackageReference Update="CommandLineParser" Version="2.9.*" />
Expand Down
8 changes: 7 additions & 1 deletion samples/star-wars-api/Startup.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@ type Startup private () =

let rootFactory (ctx) : Root = Root (ctx)

/// Added for testing purposes because in .NET 8 JsonSerializerOptions become frozen after the first use
/// and using this function caused an exception.
let configure (options : GraphQLOptions<_>) =
options.SerializerOptions.Converters.Add (new System.Text.Json.Serialization.JsonStringEnumConverter ())
options

new (configuration : IConfiguration) as this =
Startup ()
then this.Configuration <- configuration

member _.ConfigureServices (services : IServiceCollection) =
services
.AddGiraffe()
.AddGraphQLOptions<Root> (Schema.executor, rootFactory)
.AddGraphQLOptions<Root> (Schema.executor, rootFactory, configure = configure)
|> ignore

member _.Configure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,3 @@ let getWSSerializerOptions (additionalConverters: JsonConverter seq) =
options |> configureDefaultWSSerializerOptions additionalConverters
options

let serializerOptions = getWSSerializerOptions Seq.empty
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module ServiceCollectionExtensions =
SchemaExecutor = executor
RootFactory = rootFactory
ReadBufferSize = GraphQLOptionsDefaults.ReadBufferSize
SerializerOptions = Json.serializerOptions
SerializerOptions = Json.getWSSerializerOptions Seq.empty
WebsocketOptions = {
EndpointUrl = endpointUrl
ConnectionInitTimeout = TimeSpan.FromMilliseconds (GraphQLOptionsDefaults.WebSocketConnectionInitTimeoutInMs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ open FSharp.Data.GraphQL.Server.AspNetCore
open FSharp.Data.GraphQL.Server.AspNetCore.WebSockets

let toClientMessage (theInput : string) =
let serializerOptions = Json.serializerOptions
JsonSerializer.Deserialize<ClientMessage> (theInput, serializerOptions)

let willResultInInvalidMessage expectedExplanation input =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ open FSharp.Data.GraphQL.Server.AspNetCore
open FSharp.Data.GraphQL.Server.AspNetCore.WebSockets
open System.Text.Json.Serialization

let serializerOptions = Json.serializerOptions

[<Fact>]
let ``Deserializes ConnectionInit correctly`` () =

Expand Down
3 changes: 1 addition & 2 deletions tests/FSharp.Data.GraphQL.Tests/ExecutionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Execution
open FSharp.Data.GraphQL.Server.AspNetCore

type TestSubject = {
a: string
Expand Down Expand Up @@ -131,7 +130,7 @@ let ``Execution handles basic tasks: executes arbitrary code`` () =

let schema = Schema(DataType)
let schemaProcessor = Executor(schema)
let params' = JsonDocument.Parse("""{"size":100}""").RootElement.Deserialize<ImmutableDictionary<string, JsonElement>>(Json.serializerOptions)
let params' = JsonDocument.Parse("""{"size":100}""").RootElement.Deserialize<ImmutableDictionary<string, JsonElement>>(serializerOptions)
let result = sync <| schemaProcessor.AsyncExecute(ast, data, variables = params', operationName = "Example")
ensureDirect result <| fun data errors ->
empty errors
Expand Down
6 changes: 4 additions & 2 deletions tests/FSharp.Data.GraphQL.Tests/Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ open System.Threading
open System.Threading.Tasks
open Xunit
open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Server.AspNetCore

let serializerOptions = Json.getWSSerializerOptions Seq.empty

let isType<'a> actual = Assert.IsAssignableFrom<'a>(actual)
let isSeq<'a> actual = isType<'a seq> actual
Expand Down Expand Up @@ -74,11 +77,10 @@ let greaterThanOrEqual expected actual =

open System.Text.Json
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Server.AspNetCore

let stringifyArg name (ctx : ResolveFieldContext) () =
let arg = ctx.TryArg name |> Option.toObj
JsonSerializer.Serialize (arg, Json.serializerOptions)
JsonSerializer.Serialize (arg, serializerOptions)

let stringifyInput = stringifyArg "input"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ open FSharp.Data.GraphQL.Ast
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Execution
open FSharp.Data.GraphQL.Server.AspNetCore
open ErrorHelpers

let TestComplexScalar =
Expand Down Expand Up @@ -113,7 +112,7 @@ let variablesWithInput inputName input = $"""{{"%s{inputName}":%s{input}}}"""
let paramsWithValueInput input =
JsonDocument
.Parse(variablesWithInput "input" input)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

let testInputObject =
"""{"mand":"baz","opt1":"foo","opt2":null,"optSeq":["bar"],"voptSeq":["bar"],"optArr":null,"voptArr":null}"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Execution
open FSharp.Data.GraphQL.Server.AspNetCore

let stringifyArg name (ctx : ResolveFieldContext) () =
let arg = ctx.TryArg name |> Option.toObj
JsonSerializer.Serialize (arg, Json.serializerOptions)
JsonSerializer.Serialize (arg, serializerOptions)

let stringifyInput = stringifyArg "input"

Expand All @@ -45,7 +44,7 @@ let variablesWithInput inputName input = $"""{{"%s{inputName}":%s{input}}}"""
let paramsWithEnumInput input =
JsonDocument
.Parse(variablesWithInput "enumVar" input)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

[<Fact>]
let ``Execute handles enum input as variable`` () =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Execution
open FSharp.Data.GraphQL.Server.AspNetCore
open ErrorHelpers

let stringifyArg name (ctx : ResolveFieldContext) () =
let arg = ctx.TryArg name |> Option.toObj
JsonSerializer.Serialize (arg, Json.serializerOptions)
JsonSerializer.Serialize (arg, serializerOptions)

let stringifyInput = stringifyArg "input"

Expand All @@ -41,7 +40,7 @@ let variablesWithInput inputName input = $"""{{"%s{inputName}":%s{input}}}"""
let paramsWithValueInput input =
JsonDocument
.Parse(variablesWithInput "input" input)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

[<Fact>]
let ``Execute handles list inputs and nullability and allows lists to be null`` () =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Execution
open FSharp.Data.GraphQL.Server.AspNetCore

let InputArrayOf (innerDef : #TypeDef<'Val>) : ListOfDef<'Val, 'Val array> = ListOf innerDef

Expand Down Expand Up @@ -60,7 +59,7 @@ let rec TestRecursiveInputObject =

let stringifyArg name (ctx : ResolveFieldContext) () =
let arg = ctx.TryArg name |> Option.toObj
JsonSerializer.Serialize (arg, Json.serializerOptions)
JsonSerializer.Serialize (arg, serializerOptions)

let stringifyInput = stringifyArg "input"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Execution
open FSharp.Data.GraphQL.Server.AspNetCore
open ErrorHelpers

let stringifyArg name (ctx : ResolveFieldContext) () =
let arg = ctx.TryArg name |> Option.toObj
JsonSerializer.Serialize (arg, Json.serializerOptions)
JsonSerializer.Serialize (arg, serializerOptions)

let stringifyInput = stringifyArg "input"

Expand All @@ -46,7 +45,7 @@ let variablesWithInput inputName input = $"""{{"%s{inputName}":%s{input}}}"""
let paramsWithValueInput input =
JsonDocument
.Parse(variablesWithInput "input" input)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

[<Fact>]
let ``Execute handles variables and allows nullable inputs to be omitted`` () =
Expand Down Expand Up @@ -99,7 +98,7 @@ let ``Execute handles variables and allows nullable inputs to be set to a value
let paramsWithValueInput input =
JsonDocument
.Parse(variablesWithInput "value" input)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

let testInputValue = "\"a\""
let params' = paramsWithValueInput testInputValue
Expand Down Expand Up @@ -130,7 +129,7 @@ let ``Execute handles non-nullable scalars and does not allow non-nullable input
let paramsWithValueInput input =
JsonDocument
.Parse(variablesWithInput "value" input)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

let testInputValue = "null"
let params' = paramsWithValueInput testInputValue
Expand All @@ -149,7 +148,7 @@ let ``Execute handles non-nullable scalars and allows non-nullable inputs to be
let paramsWithValueInput input =
JsonDocument
.Parse(variablesWithInput "value" input)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

let testInputValue = "\"a\""
let params' = paramsWithValueInput testInputValue
Expand Down Expand Up @@ -181,7 +180,7 @@ let ``Execute uses argument default value when no argument was provided`` () =
let paramsWithOptionalInput input =
JsonDocument
.Parse(variablesWithInput "optional" input)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

[<Fact>]
let ``Execute uses argument default value when nullable variable provided`` () =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Execution
open FSharp.Data.GraphQL.Validation
open FSharp.Data.GraphQL.Validation.ValidationResult
open FSharp.Data.GraphQL.Server.AspNetCore
open ErrorHelpers

type InputRecord = { Country : string; ZipCode : string; City : string }
Expand Down Expand Up @@ -158,7 +157,7 @@ let variablesWithAllInputs (record, record1, record2, record3) =
let paramsWithValues variables =
JsonDocument
.Parse(variables : string)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

[<Fact>]
let ``Execute handles validation of valid input records from variables with all fields`` () =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ open System.Text.Json
open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Server.AspNetCore

type InputRecord = { a : string; b : string; c : string }

Expand Down Expand Up @@ -143,7 +142,7 @@ let variablesWithAllInputs (record, optRecord) =
let paramsWithValues variables =
JsonDocument
.Parse(variables : string)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (Json.serializerOptions)
.RootElement.Deserialize<ImmutableDictionary<string, JsonElement>> (serializerOptions)

[<Fact>]
let ``Execute handles creation of input records from variables with all fields`` () =
Expand Down