MissingMethodException 与 Suave & Fable.Remoting
MissingMethodException with Suave & Fable.Remoting
Here 是将重现该问题的最小示例。
尝试访问该端点,无论是使用 Fable 客户端还是导航至 http://127.0.0.1:8080/ITestAPI/Test 都会导致服务器抛出找不到方法:
[ERR] request failed
System.MissingMethodException: Method not found: 'Microsoft.FSharp.Collections.FSharpMap`2<System.String,System.Object> HttpContext.get_userState()'.
at Fable.Remoting.Suave.SuaveUtil.setBinaryResponseBody@26-1.Invoke(Unit unitVar)
at Microsoft.FSharp.Control.AsyncPrimitives.CallThenInvoke[T,TResult](AsyncActivation`1 ctxt, TResult result1, FSharpFunc`2 part2) in F:\workspace\_work\s\src\fsharp\FSharp.Core\async.fs:line 386
at Fable.Remoting.Server.Proxy.makeEndpointProxy@80-10.Invoke(AsyncActivation`1 ctxt)
at Microsoft.FSharp.Control.AsyncPrimitives.unitAsync@577.Invoke(AsyncActivation`1 ctxt) in F:\workspace\_work\s\src\fsharp\FSharp.Core\async.fs:line 577
at Program.greetFun@12-1.Invoke(AsyncActivation`1 ctxt) in C:\Users\username\code\test\suavetest\Program.fs:line 12
at Microsoft.FSharp.Control.AsyncPrimitives.unitAsync@577.Invoke(AsyncActivation`1 ctxt) in F:\workspace\_work\s\src\fsharp\FSharp.Core\async.fs:line 577
at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) in F:\workspace\_work\s\src\fsharp\FSharp.Core\async.fs:line 105
我已经为此苦苦思索了几天,没有任何进展。使用 .Net Core 3.1 和 .Net 5 时出现同样的错误。
任何人都知道可能导致这种情况的原因吗?我没有看到 Fable.Remoting 或 Suave 有任何未解决的问题,所以我不得不想象这是我做错了什么?
这看起来像是 FSharp.Core 不匹配问题。您是否依赖于低于 4.7.2 的特定 FSharp.Core 软件包?
一般来说,除非您正在编写一个旨在在 NuGet 上分发的库,否则您应该而不是 将您的依赖固定在 FSharp.Core 上。对于应用程序,请始终使用 .NET SDK 提供的任何内容,您几乎永远不会 运行 遇到这些问题。
明确地 FSharp.Core 包引用对于库作者来说是一个额外的问题,他们需要担心他们的包与哪些 F# 版本兼容。如果这不是您的要求,那么最好永远不要选择额外的复杂性。
在全新的 .NET 5 控制台应用程序中使用您的示例代码适合我:
Test.fsproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="fable.remoting.suave" Version="4.13.0" />
</ItemGroup>
</Project>
Program.fs
open System
open Suave
open Fable.Remoting.Server
open Fable.Remoting.Suave
type ITestAPI = {
Test : Async<string>
}
let greetFun =
async {
return "It works!"
}
let testAPI = {
Test = greetFun
}
let webApp =
Remoting.createApi()
|>Remoting.fromValue testAPI
|> Remoting.withDiagnosticsLogger (printfn "%s")
|>Remoting.buildWebPart
[<EntryPoint>]
let main argv =
startWebServer defaultConfig webApp
0 // return an integer exit code
在幕后,这使用了 SDK 中的 FSharp.Core 版本 4.7.0 或更高版本 ,这使其与您正在使用的库兼容并在 运行 时间没有异常。
我运行遇到了同样的问题。菲利普是正确的,但遗漏了一个重要的部分。问题是 Fable.Remoting.Suave 的当前版本是针对 Suave 2.5.6 构建的。如果您引用这个特定版本的 Suave,您可以在 .fsproj 文件中同时拥有这两个依赖项:
<ItemGroup>
<PackageReference Include="Fable.Remoting.Suave" Version="4.29.0" />
<PackageReference Include="Suave" Version="2.5.6" />
</ItemGroup>
Here 是将重现该问题的最小示例。
尝试访问该端点,无论是使用 Fable 客户端还是导航至 http://127.0.0.1:8080/ITestAPI/Test 都会导致服务器抛出找不到方法:
[ERR] request failed
System.MissingMethodException: Method not found: 'Microsoft.FSharp.Collections.FSharpMap`2<System.String,System.Object> HttpContext.get_userState()'.
at Fable.Remoting.Suave.SuaveUtil.setBinaryResponseBody@26-1.Invoke(Unit unitVar)
at Microsoft.FSharp.Control.AsyncPrimitives.CallThenInvoke[T,TResult](AsyncActivation`1 ctxt, TResult result1, FSharpFunc`2 part2) in F:\workspace\_work\s\src\fsharp\FSharp.Core\async.fs:line 386
at Fable.Remoting.Server.Proxy.makeEndpointProxy@80-10.Invoke(AsyncActivation`1 ctxt)
at Microsoft.FSharp.Control.AsyncPrimitives.unitAsync@577.Invoke(AsyncActivation`1 ctxt) in F:\workspace\_work\s\src\fsharp\FSharp.Core\async.fs:line 577
at Program.greetFun@12-1.Invoke(AsyncActivation`1 ctxt) in C:\Users\username\code\test\suavetest\Program.fs:line 12
at Microsoft.FSharp.Control.AsyncPrimitives.unitAsync@577.Invoke(AsyncActivation`1 ctxt) in F:\workspace\_work\s\src\fsharp\FSharp.Core\async.fs:line 577
at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) in F:\workspace\_work\s\src\fsharp\FSharp.Core\async.fs:line 105
我已经为此苦苦思索了几天,没有任何进展。使用 .Net Core 3.1 和 .Net 5 时出现同样的错误。
任何人都知道可能导致这种情况的原因吗?我没有看到 Fable.Remoting 或 Suave 有任何未解决的问题,所以我不得不想象这是我做错了什么?
这看起来像是 FSharp.Core 不匹配问题。您是否依赖于低于 4.7.2 的特定 FSharp.Core 软件包?
一般来说,除非您正在编写一个旨在在 NuGet 上分发的库,否则您应该而不是 将您的依赖固定在 FSharp.Core 上。对于应用程序,请始终使用 .NET SDK 提供的任何内容,您几乎永远不会 运行 遇到这些问题。
明确地 FSharp.Core 包引用对于库作者来说是一个额外的问题,他们需要担心他们的包与哪些 F# 版本兼容。如果这不是您的要求,那么最好永远不要选择额外的复杂性。
在全新的 .NET 5 控制台应用程序中使用您的示例代码适合我:
Test.fsproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="fable.remoting.suave" Version="4.13.0" />
</ItemGroup>
</Project>
Program.fs
open System
open Suave
open Fable.Remoting.Server
open Fable.Remoting.Suave
type ITestAPI = {
Test : Async<string>
}
let greetFun =
async {
return "It works!"
}
let testAPI = {
Test = greetFun
}
let webApp =
Remoting.createApi()
|>Remoting.fromValue testAPI
|> Remoting.withDiagnosticsLogger (printfn "%s")
|>Remoting.buildWebPart
[<EntryPoint>]
let main argv =
startWebServer defaultConfig webApp
0 // return an integer exit code
在幕后,这使用了 SDK 中的 FSharp.Core 版本 4.7.0 或更高版本 ,这使其与您正在使用的库兼容并在 运行 时间没有异常。
我运行遇到了同样的问题。菲利普是正确的,但遗漏了一个重要的部分。问题是 Fable.Remoting.Suave 的当前版本是针对 Suave 2.5.6 构建的。如果您引用这个特定版本的 Suave,您可以在 .fsproj 文件中同时拥有这两个依赖项:
<ItemGroup>
<PackageReference Include="Fable.Remoting.Suave" Version="4.29.0" />
<PackageReference Include="Suave" Version="2.5.6" />
</ItemGroup>