2

我在 C# 项目中使用Refit来创建 API 客户端。我更喜欢用 F# 做所有事情,但Refit 还不完全支持 F#

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

如果我添加FSharp.Core并使用FSharpOption<string>或类似方法,则尝试访问这些成员的断言会失败,NullReferenceException但只有当 JSON 响应包含可选内容时才会失败。

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

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

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

4

3 回答 3

1

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


更新:

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

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

static member FromCSharp :
    user: CSharp.User
       -> User option
于 2015-07-03T11:28:32.867 回答
0

我不确定这是否可行,但 Refit 允许您指定自定义序列化程序设置,这将允许您尝试这种方法:序列化 F# 选项类型

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

于 2015-07-02T21:08:25.467 回答
0

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

对于JSON.net,我们将其添加到需要FSharpOptionConverter的转换器列表中json.net

改装文档中,我看到了这个注释:

创建 Refit 生成的实时界面时,您可以选择传递一个 RefitSettings,它允许您指定您想要的序列化程序设置。这允许您为不同的 API 设置不同的序列化程序

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

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

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

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

于 2015-07-03T07:56:15.623 回答