FSharp.Data缺少方法异常。

4
我正在尝试解决一个预编译的F# Azure函数中的MissingMethodException问题。当我调用来自FSharp.Data.CssSelectorExtensions的扩展方法时,就会抛出此异常。
该函数定义在.NET Framework 4.6.2类库中。我正在使用当前版本的FSharp.Core(4.2.3)和FSharp.Data(2.3.3)。(我已经尝试过两者的旧版本,但问题仍然存在。)我已按照此类问题的标准指导添加了FSharp.Core的绑定重定向。代码可以编译通过,但在执行时失败。如果我尝试将扩展方法直接作为简单静态方法调用,它也会失败。
非常感谢任何关于如何消除此异常的指导!
功能代码
module httpfunc

open System.Net
open System.Net.Http
open Microsoft.Azure.WebJobs.Host
open FSharp.Data
open FSharp.Data.CssSelectorExtensions

let Run(req: HttpRequestMessage, log: TraceWriter) =
    async {
        let doc = HtmlDocument.Load("https://google.com")
        let node = doc.CssSelect("div.ctr-p") // <-- method is missing
        return req.CreateResponse(HttpStatusCode.OK)
    } |> Async.RunSynchronously

异常消息

 mscorlib: Exception while executing function: Functions.httpfunc. 
 mscorlib: Exception has been thrown by the target of an invocation. 
 fsfuncs: Method not found: 'Microsoft.FSharp.Collections.FSharpList`1<FSharp.Data.HtmlNode> CssSelectorExtensions.CssSelect(FSharp.Data.HtmlDocument, System.String)'.

app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
  </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.4.1.0" newVersion="4.4.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="FSharp.Core" version="4.2.3" targetFramework="net462" />
  <package id="FSharp.Data" version="2.3.3" targetFramework="net462" />
  ...
</packages>

.fsproj

<Project ToolsVersion="15.0" ... />
  <PropertyGroup>
    <RootNamespace>fsfuncs</RootNamespace>
    <AssemblyName>fsfuncs</AssemblyName>
    <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
    <TargetFSharpCoreVersion>4.4.1.0</TargetFSharpCoreVersion>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Name>fsfuncs</Name>
  </PropertyGroup>
  ...
</Project>

编辑

在Fyodor Soikin的建议下,我确定了FSharp.Core.dll的多个版本正在被加载:一个来自GAC,另一个来自NuGet包文件夹。

已加载两个版本的FSharp.Core.dll。


很遗憾,我不确定如何做到这一点 - 据我所知,Visual Studio目前还没有针对F# Azure Functions的调试器支持。此外,您能帮我理解当只涉及单个类库时,我该如何获得两个不同版本的FSharp.Core吗?也就是说,第二个版本会从哪里来? - John Hoerr
2
有一种方法可以在本地运行Azure Functions,查看此链接。不同的版本可能来自非常意外的地方。一个显而易见的选择是全局程序集缓存(GAC)。 - Fyodor Soikin
酷,谢谢你的指引!看起来确实加载了两个版本的 FSharp.Core.dll(请看我刚刚的编辑)。解决方案是从 GAC 中删除 FSharp.Core.dll,还是有其他方法可以防止它从那里被加载? - John Hoerr
这意味着你的 "bindingRedirect" 没有生效。现在我会验证通常的疑点:配置文件是否放置正确?版本是否正确?等等。 - Fyodor Soikin
让我们在聊天中继续这个讨论 - John Hoerr
显示剩余2条评论
1个回答

2
Azure Functions的执行引擎已经加载了FSharp.Core.dll(因为它依赖于F#编译器服务来运行您的F#脚本),我认为您将始终获得由执行引擎的app.config指定的FSharp.Core.dll版本,即4.4.0.0。
我可能会漏掉某些东西,但我认为您最好的机会是使您的函数使用4.4.0.0版本。您可以尝试删除显式的FSharp.Core引用,这样运行时应该只加载(已预加载的)FSharp.Core版本。

谢谢Tomas,这很有帮助。我一直在尽力使用打包的“FSharp.Core”,但根据Fyodor Soikin的评论,我放置的绑定重定向对于类库不起作用,因此不适合编译的函数。感谢指向执行引擎app.config的指针;这将使我的FSharp.Core GAC参考与平台版本保持同步更加容易。 - John Hoerr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接