2017-08-25 68 views
2

我試圖在預編譯的F#Azure函數中解決MissingMethodException。當我從FSharp.Data.CssSelectorExtensions調用擴展方法時拋出異常。FSharp.Data丟失方法異常

該函數在.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> 

編輯

在陀Soikin的意見,我已經確定了多個版本正在加載FSharp.Core.dll:一個來自GAC,一個來自NuGet軟件包文件夾。

Two versions of FSharp.Core.dll are loaded.

+0

我會在調試器下運行它,看看哪些模塊被加載,以及是否得到兩個不同版本的'FSharp.Core'副本。 –

+0

我不知道該怎麼做,不幸的是 - 據我所知,Visual Studio還沒有調試器支持F#Azure函數。另外,你能幫我理解我將如何獲得兩個不同版本的FSharp。核心'當只有一個類庫涉及?也就是說,第二個版本從哪裏來? –

+2

有一種方法可以在本地運行Azure函數,[檢查出來](https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local)。不同版本可能來自非常意想不到的地方。想到的一個明顯的選擇是GAC。 –

回答

1

Azure的功能背後的執行引擎已加載FSharp.Core.dll(因爲它依賴於F#的編譯器服務運行您的F#腳本),我認爲你總是會得到一個由execution engine's app.config指定的FSharp.Core.dll版本,這是4.4.0.0。

我可能會錯過一些東西,但我認爲你最好的機會是使你的函數使用版本4.4.0.0。您可以嘗試刪除顯式的FSharp.Core參考嗎?這樣,運行時應該只加載(已經預先加載的)FSharp.Core版本。

+0

感謝Tomas,這很有幫助。我盡我所能使用打包的'FSharp.Core',但根據Fyodor Soikin的評論,似乎綁定重定向對於類庫不起作用,因此不適合編譯的函數。我很欣賞指向執行引擎app.config的指針;這將使我的'FSharp.Core' GAC引用與平臺版本保持同步變得更加容易。 –