I am trying to resolve a MissingMethodException in a pre-compiled F# Azure Function. The exception is thrown when I call an extension method from FSharp.Data.CssSelectorExtensions.
The function is defined in a .Net Framework 4.6.2 class library. I am using the current versions of FSharp.Core (4.2.3) and FSharp.Data (2.3.3). (I have tried older versions of both but the problem persists.) I have added a binding redirect for FSharp.Core per the standard guidance for this kind of problem. The code compiles cleanly but fails when it is executed. It also fails if I attempt to invoke the extension method directly as a simple static method.
Any guidance on how I can get rid of this exception would be much appreciated!
Function Code
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
Exception Message
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>
Edit
On Fyodor Soikin's advice I've determined that multiple versions of FSharp.Core.dll are being loaded: one from the GAC and one from the NuGet packages folder.
The execution engine behind Azure Functions already loads FSharp.Core.dll (because it depends on F# compiler services to run your F# scripts) and I think you will always get the version of FSharp.Core.dll that is specified by the execution engine's app.config, which is 4.4.0.0.
I might be missing something, but I think your best chance is to make your function use version 4.4.0.0. Could you try removing the explicit FSharp.Core reference? That way, the runtime should load just the (already pre-loaded) version of FSharp.Core.
Related
I am struggling to resolve this runtime exception from my C# PCL that references an F# PCL:
Unhandled Exception:
System.TypeLoadException: Could not resolve type with token 0100001d
(from typeref, class/assembly Microsoft.FSharp.Core.FSharpResult`2,
FSharp.Core, Version=3.259.41.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a) occurred
NOTE:
I have ensured that my C# and F# project reference the same FSharp.Core version.
I remember having to add an XML file for versioning whenever I my test projects in F# wouldn't play nice with my F# projects. Is this the same case?
I added the following to my app config on my Xamarin.Forms PCL:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-999.999.999.999" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
But I still receive the same error.
FSharpResult is (I assume) the Result<'TSuccess, 'TError> type that was introduced in FSharp 4.1 so you should get FSharp.Core Version 4.4.1.0.
I have a Portable Library, for which the FSharp.Core version is 3.7.4.0. Installing (in the Unit Test project) FsUnit installs, as a dependency, FSharp.Core version 3.1.2.5.
Due to this, using the portable library's functions in my Unit Test project, for example:
module StammaTests.PieceTests
open Stamma
open NUnit.Framework
open FsUnitTyped
[<Test>]
let ``Testing a Basic function`` () =
Piece.toChar Black King |> shouldEqual 'k'
yields error:
Result Message: System.IO.FileLoadException : Could not load file or assembly 'FSharp.Core, Version=3.7.4.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The
located assembly's manifest definition does not match the assembly
reference. (Exception from HRESULT: 0x80131040)
Tried updating the FSharp.Core version from NuGet to 4.0.0.1 (even checking both projects when updating) and now even something simple like :
[<Test>]
let ``Testing the test`` () = 1 |> shouldEqual 1
doesn't work, giving this similar error.
Result Message: System.IO.FileLoadException : Could not load file or
assembly 'FSharp.Core, Version=4.3.1.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The
located assembly's manifest definition does not match the assembly
reference. (Exception from HRESULT: 0x80131040)
And the error for the first failing test doesn't change.
I feel like I am missing something painfully obvious, and I found several people with similar problems, but I don't understand what they did to solve it (they all seem to have solved it ..) For example this one.
Edit
Both projects are libraries and I do not have an app.config file to add anything to.
Add a binding redirect in your app.config file to redirect all FSharp.Core bindings to your desired version. For example, to use version 4.4.0, your app.config file would look something like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<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.0.0" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I found a solution that actually worked here
Basically, adding an App.config to the test project, and writing the following:
<configuration>
<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.3.1.0" newVersion="4.3.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.4.14350" newVersion="2.6.4.14350" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
It adds binding to both Fsharp.Core and NUnit.Framework, unlike the usual solutions where you only add a binding for Fsharp.Core.
I am running a solution which contains different projects. However, i am trying to run a project (class library) which contains wcf services using Visual Studio 2015 and framework 4.6 (on windows 8 OS, IIS Express). However it keeps showing this error in the browser:
Error:
I noticed that the calling assembly of Razor 2.0 is "System.Web.Mvc" Version 4.0.0.1:
Calling assembly : System.Web.Mvc, Version=4.0.0.1, Culture=neutral,
PublicKeyToken=31bf3856ad364e35.
However, System.Web.MVC dll is not referenced in this project, the references in the project are in the image below:
Although, it is not referenced it always appears in the bin folder, even when i clear it. And may be that's why it is trying to call "System.Web.WebPages.Razor" version 2.0.
Clarifying any clues of the problem:
I have no related assembly in the Web.Config that calls System.web.mvc
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
also not included in package config:
<packages>
<package id="EntityFramework" version="6.1.3" targetFramework="net46" />
<package id="Microsoft.AspNet.Providers" version="2.0.0" targetFramework="net451" />
<package id="Microsoft.AspNet.Providers.Core" version="2.0.0" targetFramework="net451" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net46" />
<package id="PostSharp" version="4.3.5-alpha" targetFramework="net46" />
<package id="System.Web.Providers" version="1.2" targetFramework="net451" />
</packages>
not included as a reference
I am wondering about whats going on? may another project affects it!
Also i have tried to use nugget to update the packages (uninstalled and reinstalled), but still in the same situation.
A possible reason of the problem:
I also noticed there is a "Gobal.asax" file in this project which uses "MvcApplication" class that implements "System.Web.HttpApplication" which may be a good reason of the problem.
Any help is appreciated.
Solution: install Microsoft.AspNet.Webpages first release of version 2.0 via nuget manager.
I would start by looking at assembly binding failures - this will show you which assembly is requesting that failing binding.
There is a handy little tool you can use to view your binding failures. This should help you track it down.
https://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.71).aspx
Good luck!
in my case, the error was after deploying, and the issue was a reference in a web.config within a sub folder of that server.
i troubleshot this by remoting into that machine and browsing the site locally (or you can enable remote errors in web.config)
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
So be sure to search all your files for 2.0.0.0 or System.Web.WebPages.Razor to make sure there is no reference somewhere!
I was getting this error, but the project from which the error is throwing has the Microsoft.AspNet.Webpages installed properly. Then I realised that the WCF services which are kept in a separate project lost it's MVC installation.
So installing Microsoft.AspNet.Mvc in my other project fixed this error for me.
I'm trying to use unquote with NUnit as the test runner. The test case is taken from Getting Started and works as expected when run outside of NUnit:
namespace FsTest.Tests
open NUnit.Framework
open Swensen.Unquote
[<TestFixture>]
module Example =
[<Test>]
let foo() =
test <# (1+2)/3 = 1 #>
Under NUnit I get this exception:
FsTest.Tests.Example.foo: System.MissingMethodException : Method not
found:
'System.Tuple2<Microsoft.FSharp.Collections.FSharpList1,Microsoft.FSharp.Quotations.FSharpExpr>
Internal.reduceFullyAndGetLast(Microsoft.FSharp.Quotations.FSharpExpr)'.
I'd like to know if there's anything wrong with the code above and how I could make it work. Unquote's raise fail for me in the same way if that helps.
Based on the description of your problem, I suspect you need to configure your NUnit project with an FSharp.Core binding redirect from version 4.0.0.0 to version 4.3.0.0 since the latest version of Unquote is built for .NET 4.0 and your test project targets .NET 4.5.
See this Unquote issue for details. I believe your configuration would look something like
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity
name="FSharp.Core"
publicKeyToken="b03f5f7f11d50a3a"
culture="neutral"/>
<bindingRedirect
oldVersion="2.0.0.0"
newVersion="4.3.0.0"/>
<bindingRedirect
oldVersion="4.0.0.0"
newVersion="4.3.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I'm not sure exactly where you would need to put this for an NUnit project, but maybe in the config file specified through the Project Editor?
Unfortunately, I don't have VS2012 installed and so I am somewhat crippled in my ability to really diagnose this issue for you.
After I installed VS11, I started to get the following error:
Consider app.config remapping of assembly "FSharp.Core, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" from Version "2.0.0.0" [C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\2.0\Runtime\v2.0\FSharp.Core.dll] to Version "4.0.0.0" [C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\2.0\Runtime\v4.0\FSharp.Core.dll] to solve conflict and get rid of warning.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1490,5): warning MSB3247: Found conflicts between different versions of the same dependent assembly.
What exactly should I do? I have no idea how to do such a remapping.
Below is I think a sample app.config that does what is suggested. However, what is in your project, and what FSharp.Core reference is there? Are you targeting .Net 4.5 or 4.0 or what? Does this project reference some older F# library? This typically is because two projects reference different versions of FSharp.Core.dll, e.g. check the <Reference> nodes in the .fsproj files.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a"
culture="neutral"/>
<!-- <bindingRedirect oldVersion="0.0.0.0-2.9.9.9" newVersion="4.3.0.0"/> -->
<bindingRedirect oldVersion="2.0.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
same error related to Json.Net
In project file I had
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.6.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
and
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
Deleting the old one solved the problem.
If you have accomplished upgrade well, there should be no such issue... Unless you're using some third party library, that uses old FSharp.Core itself. In my case it's FSharpPowerPack who does this.
So you have to either update that library first to get rid of this message.