MissingMethodException with Suave & Fable.Remoting - f#

Here is a minimal sample that will reproduce the issue.
Trying to hit that endpoint, either with a Fable client or just navigating to http://127.0.0.1:8080/ITestAPI/Test causes the server to throw a Method not found:
[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\1\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\1\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\1\s\src\fsharp\FSharp.Core\async.fs:line 577
at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\async.fs:line 105
I've hit my head against this for a couple of days now, with no progress. Same error occurs using both .Net Core 3.1 and .Net 5.
Anyone have any insight into what might be causing this? I'm not seeing any open issues with Fable.Remoting or Suave about this, so I have to imagine it's something I'm doing wrong?

This looks like an FSharp.Core mismatch issue. Are you depending on a specific FSharp.Core package that is less than 4.7.2?
In general, unless you are writing a library intended for distribution on NuGet, you should not pin your dependency on FSharp.Core at all. For applications, always use whatever the .NET SDK provides and you'll virtually never run into these issues.
Explicitly FSharp.Core package references are an additional issue for library authors who need to worry about which F# versions their package is compatible with. If that is not a requirement for you, then it's best to never opt into that additional bit of complexity.
Using your sample code in a brand-new .NET 5 console app works for me:
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
Under the covers, this uses the FSharp.Core in the SDK that is version 4.7.0 or higher, which makes it compatible with the library you're using and results in no exception at runtime.

I ran into the same issue. Phillip is correct, but is missing an important piece. The problem is that the current version of Fable.Remoting.Suave is built against Suave 2.5.6. If you reference this specific version of Suave, you can have both dependencies in your .fsproj file:
<ItemGroup>
<PackageReference Include="Fable.Remoting.Suave" Version="4.29.0" />
<PackageReference Include="Suave" Version="2.5.6" />
</ItemGroup>

Related

How to make FSI work under NET5 and make stupid stackoverflow message "Title cannot contain ..." shut up?

I am migrating a fairly small F# project from Net Framework to NET5. The migration was very easy and everything works including the tests.
However, when I run some scripts I am now getting the following error:
Microsoft (R) F# Interactive version 11.0.0.0 for F# 5.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
>
[Loading C:\Users\kkkma\AppData\Local\Temp\nuget\28772--091a5e4a-2a27-4d4d-9891-2b58055c5317\Project.fsproj.fsx
Loading C:\GitHub\Berreman\Berreman\Analytics\Examples\References.fsx]
namespace FSI_0002.Project
namespace FSI_0002
[Loading C:\Users\kkkma\AppData\Local\Temp\nuget\28772--091a5e4a-2a27-4d4d-9891-2b58055c5317\Project.fsproj.fsx]
namespace FSI_0003.Project
Binding session to 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.dll'...
Binding session to 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Numerics.dll'...
System.TypeLoadException: Could not load type 'System.ICloneable' from assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
at Berreman.MathNetNumericsMath.complexDiagonalMatrix(Int32 n, Complex e)
at Berreman.Geometry.complexIdentityMatrix(Int32 n) in C:\GitHub\Berreman\Berreman\Berreman\Geometry.fs:line 17
at Berreman.Geometry.ComplexMatrix3x3.get_identity() in C:\GitHub\Berreman\Berreman\Berreman\Geometry.fs:line 307
at Berreman.MaterialProperties.Eps.fromRefractionIndex(RefractionIndex _arg1) in C:\GitHub\Berreman\Berreman\Berreman\MaterialProperties.fs:line 70
at FSI_0004.opticalProperties(RefractionIndex refractionIndex) in C:\GitHub\Berreman\Berreman\Analytics\Examples\Glass_01.fsx:line 51
at FSI_0004.getGlassInfo(Boolean useThickPlate, RefractionIndexThickness nh1, FSharpOption`1 nh2Opt, IncidentLightInfo light) in C:\GitHub\Berreman\Berreman\Analytics\Examples\Glass_01.fsx:line 61
at <StartupCode$FSI_0004>.$FSI_0004.main#() in C:\GitHub\Berreman\Berreman\Analytics\Examples\Glass_01.fsx:line 98
Stopped due to error
>
When I examine Project.fsproj.resolvedReferences.paths from C:\Users\kkkma\AppData\Local\Temp\nuget\28772--091a5e4a-2a27-4d4d-9891-2b58055c5317 (and that's the folder created by FSI when I run the script) I see that it starts from C:\Users\kkkma\.nuget\packages\microsoft.netframework.referenceassemblies.net48\1.0.0\build\.NETFramework\v4.8\Facades\System.Runtime.InteropServices.RuntimeInformation.dll and it also has some other Net Framework resolved references. Which makes me believe that FSI somehow "decides" to use Net Framework instead of NET 5.
The file fsi.runtimeconfig.json contains correct information:
{
"runtimeOptions": {
"tfm": "net5.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "5.0.0"
}
}
}
Does anyone have an idea how to force FSI pick up NET 5 instead of Net Framework?
As of Visual Studio 2019 version 16.9, you can enable an option to use dotnet fsi to run interactive F# scripts. This works with .NET 5 code.
This is set via Tools > Options > F# Tools > F# Interactive > Use .NET Core Scripting.
Full details and instructions can be found at https://devblogs.microsoft.com/dotnet/f-and-f-tools-update-for-visual-studio-16-9/

Why am I getting this error when trying to implement UseNetTopologySuite in my ASP.Net Core 2.2 api?

I am attempting to use the geometry functionality in Sql Server and EF Core.
I've installed the following packages
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite" Version="2.2.6" />
<PackageReference Include="NetTopologySuite" Version="2.0.0" />
In my Startup.cs, I have the following:
services.AddDbContextPool<CRFlowContext>(options =>
options.UseSqlServer("connection string", x => x.UseNetTopologySuite());
});
Everything builds fine, but when I attempt to run the app, I get the following error:
Application startup exception: System.MissingMethodException: Method not found: 'GeoAPI.IGeometryServices NetTopologySuite.NtsGeometryServices.get_Instance()'.
at Microsoft.Extensions.DependencyInjection.SqlServerNetTopologySuiteServiceCollectionExtensions.AddEntityFrameworkSqlServerNetTopologySuite(IServiceCollection serviceCollection)
at Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal.SqlServerNetTopologySuiteOptionsExtension.ApplyServices(IServiceCollection services)
at Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.ApplyServices(IDbContextOptions options, ServiceCollection services)
at Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.<>c__DisplayClass4_0.<GetOrAdd>b__2(Int64 k)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.EntityFrameworkCore.Internal.ServiceProviderCache.GetOrAdd(IDbContextOptions options, Boolean providerRequired)
at Microsoft.EntityFrameworkCore.DbContext..ctor(DbContextOptions options)
at Entities.CRFlowContext..ctor(DbContextOptions`1 options) in C:\Src\myproj\myproj.Entities\MyProjContext.cs:line 11
at lambda_method(Closure )
at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.Rent()
at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.Lease..ctor(DbContextPool`1 contextPool)
I suspect this has to do with creating my entity in the Program.cs and injecting it into the rest of the app.
Any ideas on how to fix this?
You need to delete the NetTopologySuite library
And just use Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite.
For anyone looking at this, it turns out that you need to install the NetTopologySuite.Core, not NetTopologySuite.
Once I installed this, it worked fine.

Use Custom Patterns in ReSharper Code Quality Analysis in TFS build

I use ReSharper 2017.2.2 on the development machine together with Visual Studio 2017.5.
I'm using TFS 2017 Update 3.
On the TFS server, Visual Studio 2017.4 and ReSharper CLT 2017.2.2 are installed.
I'm using TFS build.
My goal is to do code analysis when building a solution.
I use the Resharper Code Quality Analysis task. I can configure it using the sln.DotSettings file which is at the root of the solution.
Standard code checks ReSharper successfully work. I can also change the warning level as shown here https://marketplace.visualstudio.com/items?itemName=alanwales.resharper-code-analysis
For this I use ReSharper -> Options | Code Inspection -> Custom patterns.
This rule works well in Visual Studio. When I save this rule to sln.DotSettings, the following lines are added:
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=4E6B3830DEEA6148909C23CD21C96E28/#KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=4E6B3830DEEA6148909C23CD21C96E28/LanguageName/#EntryValue">JAVA_SCRIPT</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=4E6B3830DEEA6148909C23CD21C96E28/MatchCatchClauseWithoutExceptionFilter/#EntryValue">False</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=4E6B3830DEEA6148909C23CD21C96E28/SearchPattern/#EntryValue">debugger</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=4E6B3830DEEA6148909C23CD21C96E28/Severity/#EntryValue">ERROR</s:String></wpf:ResourceDictionary>
I in the JS code specially added lines with debugger. But I do not get a warning on my custom patterns.
Does Resharper Code Quality Analysis support in TFS use Custom patterns?
UPDATE 1: I checked the launch of the code analysis via the console with the command: InspectCode.exe -o="C:\temp\Results.xml" --no-swea "C:\BuildAgent\Thompson\_work\23\s\***.sln"
In the Results.xml file, I found the required line:
<Issue TypeId="StructuralSearch" Severity="ERROR" File="***.WebResources\WebResources\new_\js\forms\***.js" Offset="406-415" Line="13" Message="debugger" />
UPDATE 2: I looked at the script code RunResharperCodeAnalysisTool.ps1. In this file there are the following lines:
...
$severityLevels = #{"Hint" = 0; "Suggestion" = 1; "Warning" = 2; "Error" = 3}
...
foreach($issue in $issuesElements) {
$severity = #($issuesTypesElements | Where-Object {$_.Attributes["Id"].Value -eq $issue.Attributes["TypeId"].Value})[0].Attributes["Severity"].Value
$severityLevel = $severityLevels[$severity]
if($severityLevel -ge $severityLevels[$failBuildLevelSelector]) {
$item = New-Object -TypeName PSObject -Property #{
'Severity' = $severity
'Message' = $issue.Attributes["Message"].Value
'File' = $issue.Attributes["File"].Value
'Line' = $issue.Attributes["Line"].Value
}
$filteredElements.Add($item)
}
}
The Results.xml file has the following lines:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by JetBrains Inspect Code 2017.2.2 -->
<Report ToolsVersion="109.0.20171006.123742">
<Information>
<Solution>..\..\BuildAgent\Thompson\_work\23\s\***\***.sln</Solution>
<InspectionScope>
<Element>Solution</Element>
</InspectionScope>
</Information>
<IssueTypes>
<IssueType Id="StructuralSearch" Category="Structural Search Highlightings" CategoryId="StructuralSearch" Description="Structural Search Pattern" Severity="INVALID_SEVERITY" />
<IssueType Id="WebConfigErrors" Category="WebConfig Errors" CategoryId="WebConfigErrors" Description="" Severity="ERROR" />
</IssueTypes>
<Issues>
<Project Name="***">
<Issue TypeId="WebConfigErrors" File="***.WebResources\Web.config" Offset="531-650" Line="17" Message="Invalid module qualification: Failed to resolve assembly Microsoft.CodeDom.Providers.DotNetCompilerPlatform" />
<Issue TypeId="WebConfigErrors" File="***.WebResources\Web.config" Offset="916-1035" Line="20" Message="Invalid module qualification: Failed to resolve assembly Microsoft.CodeDom.Providers.DotNetCompilerPlatform" />
<Issue TypeId="StructuralSearch" Severity="ERROR" File="***.WebResources\WebResources\new_\js\forms\***.js" Offset="406-415" Line="13" Message="debugger" />
</Project>
</Issues>
</Report>
My Custom Patterns has Severity="INVALID_SEVERITY" which is not on the $severityLevels list.
Since it works well with the command line, seems the issue is not related to TFS side, may more related with the 3-party task.
If this will not work with the Resharper Code Quality Analysis task, you could directly call the InspectCode.exe command during the build task by use a command line task or customize extension. Then publish the result file to TFS.
Besides, as a workaround, you could also be able to return warnings and errors from your powershell script using logging commands. With using task.logissue type=error you could fail the build task and then fail the build.

BDD with Specflow in Visual Studio 2017 -featurefile Error CS1029

I am trying out BDD with Specflow in Visual Studio 2017. Previously I had created a new project and added Specflow and Nunit using NuGet Package Manager. From the Solution Explorer, I right click and select Add New Item. From the Add New Item window, I could see SpecFlow feature File and Feature.cs file
But I open the Feature.cs it's showing empty with the message
<#error Generation error: The element may only appear once in this section.>
Then I try to build the solution then I'm getting error on Output
Error CS1029
error: 'Generation error: The element may only appear once in this section.'
The references I can see from Solution Explorer are: SpecRun.SpecFlowPlugin TechTalk.SpecFlow TechTalk.SpecRun NUnit.VisualStudio.TestAdapter
Am I missing something?
Thanks, Mohammed
If you have a scenario outline, but you for get to write the Examples-Keyword, you will get the following error during the build process:
CS1029 #error: 'Generation error: Sequence contains no elements' in Line 1 of MyFeature.feature
It took me some hours in my large created feature file to locate my error. I deleted the temp files, restarted visual studio several times, but it was difficult to figure out why it occurs.
Could you somehow improve the error messages e.g. with a better location, a simple syntax check before or something similar?
As far as I understand, the ScenarioOutline, followed by a will allways need at least an Examples keyword and a table with this varname, before an other Tag like Scenario, etc. is allowed again. I would appreciate to have such markup
?xml version="1.0" encoding="utf-8"?>
configuration>
<configSections>
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
</configSections>
<specFlow>
<!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config -->
<!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config --><!-- use unit test provider SpecRun+NUnit or SpecRun+MsTest for being able to execute the tests with SpecRun and another provider --><unitTestProvider name="SpecRun" /><plugins>
<add name="SpecRun" />
</plugins></specFlow>
</configuration>

Using F# Result discriminated union results in TypeLoadException

I've refactored some of my code to use (relatively newly introduced) F# Result type that is defined in FSharp.Core like this:
type Result<'TOk,'TError> =
| Ok of 'TOk
| Error of 'TError
Everything compiles but at runtime the application fails with the following exception:
Could not load type 'Microsoft.FSharp.Core.FSharpResult`2' from
assembly 'SomeAssembly, Version=1.25.24.0, Culture=neutral,
PublicKeyToken=null' due to value type mismatch.
If I copy the definition to my project so it shadows the original one, everything works.
The app.config has the following section:
<dependentAssembly>
<Paket>True</Paket>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="4.4.1.0" />
</dependentAssembly>
And the projects files are updated with the directive <TargetFSharpCoreVersion>4.4.1.0</TargetFSharpCoreVersion>
So I am not really sure what can cause this error. What is also strange is that the error message claims that FSharpResult is supposed to reside in project assembly, rather than FSharp.Core.dll.
UPDATE. As suggested in the comments, the problem only occurs when the application is built using Visual Studio 2015. Here's a small console program that reproduces the problem:
open System
[<EntryPoint>]
let main argv =
let result = Result.Ok "Hello"
printfn "%A" result
0
Open Visual Studio 2015, build and run the project, you should see this error:
Unhandled Exception: System.TypeLoadException: Could not load type
'Microsoft.FSharp.Core.FSharpResult`2' from assembly
'ResultTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' due to value type mismatch.
at Program.main(String[] argv)
If you have Visual Studio 2017 and rebuild the app with it, the app will work fine and prints the result:
Ok "Hello"
This is caused by F# 4.0 compiler using together with FSharp.Core 4.4.1.0, as described here:
https://github.com/Microsoft/visualfsharp/issues/3354
Workaround: Add FSharp.Compiler.Tools NuGet package to the affected projects as long as Visual Studio 2015 is used. Visual Studio 2017 works fine.
In my case, using VS2015 IDE was a must, so we implemented our own version of the Result type:
type Result<'t, 'e> = | Ok of 't | Error of 'e
or you can even fine tune the type with your own error handling requirements, e.g.:
type Result<'t> =
| Success of 't
| Failure of (string * exn option)
or
type Result<'t> =
| Success of 't
| Failure of (ErrorCode * string)
and ErrorCode = | Code1 | Code2 | Code3
I know it's not ideal, it's better if you have this types available in the F# core, but it did the trick :)

Resources