Reputation: 8999
I am experiencing issues when consuming a certain C# type in an F# web application. The following C# type is present in a library I refer to in my F# app:
public static class OuterType
{
public class Model
{
private readonly string id;
private readonly bool selected;
private string name;
internal Model() : this(string.Empty) { }
public Model(string id) : this(id, false) { }
public Model(string id, bool selected)
{
this.id = name = id;
this.selected = selected;
}
[Localizable(false)]
public string ID => id;
public bool Selected => selected;
[Localizable(true)]
public string Name
{
get => name;
set => name = value;
}
}
}
I have written a proxy for it (as part of my F# web app):
[<Proxy(typeof<OuterType.Model>)>]
type ProxyModel =
{
ID : string
Selected : bool
Name : string
}
My project compiles fine, but I am receiving a runtime serialization error:
System.Exception: Error during RPC JSON conversion ---> System.Exception: Failed to look up translated field name for id in type OuterType+Model with fields: Name, Selected, Id
This lead me to believe the converter is looking to match the type by field names. So I changed my proxy as follows:
[<Proxy(typeof<OuterType.Model>)>]
type ProxyModel =
{
id : string
selected : bool
name : string
}
The above leads to a compilation error:
WebSharper error FS9001: Could not find field of F# record type: OuterType.Model.Selected WebSharper error FS9001: Could not find field of F# record type: OuterType.Model.Name
and I am stuck. Is there anything I am missing?
The application is targeting netcoreapp2.1. It uses the following WebSharper dependencies (excerpt from my paket.lock):
WebSharper (4.5.9.330)
WebSharper.AspNetCore (4.5.3.104)
WebSharper.FSharp (4.5.9.330)
WebSharper.Html (4.5.1.153)
WebSharper.Reactive (4.5.1.139)
WebSharper.UI (4.5.8.161)
Upvotes: 1
Views: 101
Reputation: 391
WebSharper remoting uses reflection to create/read objects, so if they are classes, they must follow rules in https://developers.websharper.com/docs/v4.x/cs/remoting#heading-6.
In this case, the only change you need is to make the parameterless constructor public.
Once you have that, you can use the C# type for RPC, but still for client-side use, you need a either [JavaScript]
on the type (with WebSharper and WebSharper.CSharp packages added for the C# project), or a proxy that matches it well, including constructors which you won't be able to reproduce with an F# record, you might need a class.
Upvotes: 0