I'm caling an API using Flurl.
//# models.fs
module models =
type Ticker = { Ask :decimal; Bid :decimal; Last: decimal; High :decimal; Timestamp :int; }
//# Client.fs
namespace MyLibrary
// ... some code
url.GetJsonAsync<models.Ticker>()
This works and I can access the ticker.Ask property.
The class models.Ticker is visible from another C# project and the construcor is this:
public Ticker(decimal ask, decimal bid, decimal last, decimal high, int timestamp);
I don't want expose the models module and the Ticker class/record so I changed the visibility to internal:
# models.fs
module internal models =
type Ticker = { Ask :decimal; Bid :decimal; Last: decimal; High :decimal; Timestamp :int; }
The code still "compile" but when I run it I have this exception:
- Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type MyProject.models+Ticker. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'high', line 1, position 8. at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader) at Flurl.Http.Configuration.NewtonsoftJsonSerializer.Deserialize[T](Stream stream) at Flurl.Http.HttpResponseMessageExtensions.ReceiveJson[T](Task`1 response)} System.Exception {Newtonsoft.Json.JsonSerializationException}*
This is the full code example, I'm new with F#, maybe needed to explain the problem:
open Flurl.Http
// open mynamespace where is models
type IClient =
abstract member GetAsk : decimal
type MyClient() =
let getTicker () =
let url = "https://www.bitstamp.net/api/v2/ticker/XRPUSD"
url.GetJsonAsync<models.Ticker>()
interface IClient with
member __.GetAsk =
let ticker = getTicker().Result
ticker.Ask
I'm using the Client from a C# project. I imagine the constructor of Ticker changed because of the visibility. But, why? How can I maintain the Ticker class hidden and make the code works as expected?
[Update: use a class]
Using a class
type internal Ticker(ask:decimal, bid :decimal, last: decimal, high :decimal, timestamp :int) =
member this.Ask = ask
does the job as expected.
If internal it is not visible externally but it is "usable" by the JsonDeserializer.
I'm still confused for the behavior when I use a Record.