我应该如何在 F# 项目中从 Refit 序列化 JSON?

How should I serialize JSON from Refit in an F# project?

我正在使用 Refit in a C# project to create an API client. I'd prefer to do everything with F# but Refit doesn't fully support F# yet

如果我在 C# 中创建我的 User 模型,一切都很好,但我希望能够表达哪些属性是可选的并适当地处理它们。

如果我添加 FSharp.Core 并使用 FSharpOption<string> 或类似的,则尝试访问这些成员的断言会失败并显示 NullReferenceException 但前提是 JSON 响应包含某些内容可选。

如果我创建一个包含 User 模型的单独 F# 项目,我在尝试反序列化时总是得到 NullReferenceException

诚然,将任何模型保留为 C# 项目的一部分似乎更容易,但我不想牺牲了解哪些成员在 F# 端是可选的。

解决此问题的最佳方法是什么?

我不确定这是否有效,但 Refit 允许您 specify custom serializer settings, which will allow you to try this approach: Serializing F# Option types

如果这不起作用,请创建一个小的重现项目并创建一个问题,我会调查它。

我不熟悉 Refit,但这里有一些 FSharpOption<> 我们在生产中使用的转换器代码 https://gist.github.com/NickJosevski/956246019c431630931b

对于 JSON.net,我们将 FSharpOptionConverter 添加到 json.net 采用的转换器列表中。

refit 上的文档中,我看到了这条注释:

When creating a Refit generated live interface, you may optionally pass a RefitSettings that will allow you to specify what serializer settings you would like. This allows you to have different serializer settings for separate APIs

所以在我的代码中,JsonSerializerSettings 设置是这样的:

var settings = new JsonSerializerSettings()
{
    TypeNameHandling = TypeNameHandling.Auto,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    Formatting = Formatting.Indented
};

// important bit:
 settings.Converters.Add(new FSharpOptionConverter());

因此,如果您能找到正确的位置来连接这些设置,那么反序列化应该适用于 FSharpOption<>

我目前的想法是按原样保留 C# 项目并创建一个 F# 包装器,该包装器 returns 以 Result 类型建模,并在适当的地方使用可选成员。


更新:

我最终这样做并将以下内容添加到我的 FSharp 模型中:

static member ToCSharp :
    user: User
       -> CSharp.User

static member FromCSharp :
    user: CSharp.User
       -> User option