Open JordanMarr opened 1 year ago
I came up with the following workaround to allow editing individual fields:
module Extensions
open FSharp.Data
open FSharp.Data.JsonExtensions
/// Extension methods to allow overwriting read-only properties on generated types.
type JsonValue with
member private this.SetValue(jsonProperty: string, value: JsonValue) =
let idx = this.Properties |> Array.findIndex (fun (pNm, _) -> pNm = jsonProperty)
this.Properties[idx] <- jsonProperty, value
/// Sets a json property on a generated type.
member this.Set(jsonProperty: string, value: JsonValue) =
this.SetValue(jsonProperty, value)
/// Sets a json property on a generated type.
member this.Set(jsonProperty: string, value: string) =
this.SetValue(jsonProperty, JsonValue.String value)
/// Sets a json property on a generated type.
member this.Set(jsonProperty: string, value: decimal) =
this.SetValue(jsonProperty, JsonValue.Number value)
/// Sets a json property on a generated type.
member this.Set(jsonProperty: string, value: float) =
this.SetValue(jsonProperty, JsonValue.Float value)
/// Sets a json property on a generated type.
member this.Set(jsonProperty: string, value: bool) =
this.SetValue(jsonProperty, JsonValue.Boolean value)
[<Test>]
let ``Create RFI Entity`` () =
let rfi = RfiTypes.GetSample()
rfi.Subject =! "Wall Color"
// manually overwrite a read-only property value
rfi.JsonValue.Set("subject", "New Subject")
rfi.Subject =! "New Subject"
It's not perfect as I lose some of the benefits of having strongly typed entities; however, it still saves me from having to manually generate large entities, and since I only need to edit a handful of properties, it seems like a pretty good workaround.
It would be a lot more strongly typed if there was an option of having writable properties though.
Is it possible for the JsonProvider to generate types with writable properties?
My use case is that I have a rather large JSON sample object that I want to create a new instance of using the default values in my sample and then manually modify only a few select fields. However, the read-only nature of the generated properties prevents me from using this technique, leaving only the option of initializing every value via the constructor.