So I have the following F# method
static member ReadInstagramSearch() =
let data = Http.Request( "https://api.instagram.com/v1/users/search?q=SomeUSer&client_id=someclientid" )
let res = FsUserSearch.Parse(data)
res.Data.[0]
If I have a C# controller that I call this method with is there anyway to use that result in the View? I've tried just simple access with
@Model.FirstName
but that gives me an exception
'FSharp.Data.RuntimeImplementation.JsonDocument' does not contain a definition for 'FirstName'
Is my only option to turn that JsonDocument into a strongly typed Model object? And then return that?
This is using http://fsharp.github.io/FSharp.Data/library/JsonProvider.html
And my JsonProvider is defined as
type FsUserSearch = JsonProvider<"""
{
"data": [{
"username": "jack",
"first_name": "Jack",
"profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_66_75sq.jpg",
"id": "66",
"last_name": "Dorsey"
}]
}""">
Sadly, this is not supported at the moment. The JSON type provider uses erased types which means that the parsed document is represented as a value of type JsonDocument
that does not actually have any of the members that you can see in F#. The F# compiler understands this, but they are not present in compiled code and other languages do not support type providers at the moment.
There is a number of ways to fix this and it is certainly on the TODO list. (It is a bit tricky, implementing ICustomTypeDescriptor
would work in some scenarios, but not here. Generating actual types might be a way forward. For more information, see this bug at F# Data GitHub page.)
For now, you might be able to use the dynamic access operations that the JSON library provides. See the JSON Parser and Reader page for more details. I think @Model.FirstName
could be done using:
@Model.GetProperty("FirstName").AsString()
Certainly not perfect - but sadly C# does not support type providers, so this is probably the best option. Another workaround would be to define a simple F# record type and transform the data you need into a record type that you can then easily use from C#.