我应该如何在 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
我正在使用 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