How to get Elmah working with .Net 6 F# Web Api Project - f#

I've used Elmah before in a C# project years ago and I have recently started using F# and having a bit of trouble. I have a .Net 6 Web Api project
from This Post I see the key code is:
services.AddElmah<SqlErrorLog>(options =>
{
options.ConnectionString = "Server=localhost;Database=ELMAH;Integrated Security=True;";
});
I am a bit lost as to how to actually get this working in my F# program.fs
It currently looks like this:
[<EntryPoint>]
let main args =
let builder = WebApplication.CreateBuilder(args)
builder.Services.AddControllers()
let app = builder.Build()
app.UseHttpsRedirection()
app.UseAuthorization()
app.MapControllers()
app.Run()
exitCode

The equivalent in F#, and with asp.net minimal API that you are using, would be to put this before let app = ...:
builder.Services.AddElmah<SqlErrorLog>(fun options ->
options.ConnectionString <- "Server=localhost;Database=ELMAH;Integrated Security=True;"
)

Related

How to call Q# operations from F#

I want to write a quantum program in F# but I don't know how to call Q# operations from F#. How exactly would I do this?
I've tried reading the C# version first but it doesn't seem to translate well to F#.
TL;DR: You have to create a Q# library project (which will yield a .csproj project with only Q# files in it) and to reference it from a purely F# application.
You can not mix F# and Q# in the same project, because it won't compile: Q# compiles to C# for local simulation, and you can't have C# and F# in the same projects. However, you can have two separate projects in different languages which both compile to MSIL and can reference each other.
The steps are:
Create Q# library QuantumCode and write your code in it.
Let's say your code has an entry point with the signature operation RunAlgorithm (bits : Int[]) : Int[] (i.e., it takes an array of integers as a parameter and returns another array of integers).
Create an F# application (for simplicity let's make it a console app targeting .NET Core) FsharpDriver.
Add a reference to the Q# library to the F# application.
Install the NuGet package Microsoft.Quantum.Development.Kit which adds Q# support to the F# application.
You will not be writing any Q# code in FsharpDriver, but you will need to use functionality provided by the QDK to create a quantum simulator to run your quantum code on, and to define data types used to pass the parameters to your quantum program.
Write the driver in F#.
// Namespace in which quantum simulator resides
open Microsoft.Quantum.Simulation.Simulators
// Namespace in which QArray resides
open Microsoft.Quantum.Simulation.Core
[<EntryPoint>]
let main argv =
printfn "Hello Classical World!"
// Create a full-state simulator
use simulator = new QuantumSimulator()
// Construct the parameter
// QArray is a data type for fixed-length arrays
let bits = new QArray<int64>([| 0L; 1L; 1L |])
// Run the quantum algorithm
let ret = QuantumCode.RunAlgorithm.Run(simulator, bits).Result
// Process the results
printfn "%A" ret
0 // return an integer exit code
I posted a full example of the project code here (originally that project dealt with using Q# from VB.NET, but for F# all the steps are the same).

Building and running FsCheck.Xunit tests in an F# ionide project

I created a standalone console application using the yo fsharp generator. The github repo concerning this particular question is here: https://github.com/KurtRMueller/PascalsTriangleKata.
I'd like to build and run some basic FsCheck.Xunit tests. I'm aware that I need to add some targets to FAKE's build.fsx, but as I'm quite new to .net and the C#/F# ecosystem, I don't know how to do that.
The example from the FAKE example page is as follows:
// define test dlls
let testDlls = !! (testDir + "/Test.*.dll")
Target "xUnitTest" (fun _ ->
testDlls
|> xUnit (fun p ->
{p with
ShadowCopy = false;
HtmlOutput = true;
XmlOutput = true;
OutputDir = testDir })
)
I'm not quite sure how to build the these Test dlls.
Any help is appreciated. Thanks.

F# SignalR Dynamic Class

I am working through a tutorial on SignalR using F# and I have run into a problem. The SignalR IHubConnectionContext has an .All property that is dynamic. You are supposed to define the method here that the client will wire up to receive notifications from the server. It works fine in C#. However, in F#, I am getting:
The field, constructor or member 'yourMethodHere' is not defined
Does anyone have any ideas? Thanks in advance.
I've used self hosting signalr in F# it works just fine. I also have two different libraries that can bridge this gulf you are having.
A.
You can use my apache licensed open source library FSharp.Interop.Dynamic (PCL w/ .net 4.5, WinRT, Silverlight 5.0) that implements the late binding operator ? using the DLR.
open FSharp.Interop.Dynamic
...
Clients.All?yourMethodHere(some, args)
B.
If you want a little more typing. I also wrote another apache licensed library ImpromptuInterface (.net 4.0 or Silverlight 5.0) that will generate an Interface to dlr proxy. Such that you can define an interface to talk to dlr objects.
type IClientsAll =
abstract yourMethodHere : string * string -> unit
...
open ImpromptuInterface
...
let clientsAll = Clients.All.ActLike<IClientsAll>()
clientsAll.yourMethodHere(some, args)

MvcIntegrationTestFramework or an alternative updated for ASP.NET MVC 3

I'm interested in using Steve Sanderson’s MvcIntegrationTestFramework or a very similar alternative with ASP.NET MVC 3 Beta.
Currently when compiling MvcIntegrationTestFramework against MVC 3 Beta I get the following error due to changes in MVC:
Error 6
'System.Web.Mvc.ActionDescriptor.GetFilters()' is obsolete: '"Please call System.Web.Mvc.FilterProviders.Providers.GetFilters() now."' \MvcIntegrationTestFramework\Interception\InterceptionFilterActionDescriptor.cs Line 18
Questions
Can anybody provide the MvcIntegrationTestFramework working for ASP.NET MVC 3 Beta?
--- and / or ---
Are there similar alternatives you would recommend?
EDIT #1: Note I have e-mailed Steve the creator of MvcIntegrationTestFramework, also hoping for some feedback there.
EDIT #2 & #3: I have received a message from Steve. Quoted for your reference:
I haven't needed to use that project with MVC 3, so sorry, I don't have an updated version of it. As far as I'm aware it should be possible to update it to work on MVC 3, but you'd need to figure that out perhaps by inspecting the MVC 3 source code to notice any changes in how actions, filters, etc are invoked now. If you do update it, and if you decide to adopt it as an ongoing project (e.g., putting it on Github or similar), let me know and I'll post a link to it! (Thanks Steve!)
EDIT #4: Honestly had a quick stab at using System.Web.Mvc.FilterProviders.Providers.GetFilters() didn't get anywhere fast and simply adding the [Obsolete] found that there was an error in the internals of the MVC requests. Anybody else had a dabble?
EDIT #5: Please comment if you are using an alternative Integration Test Framework with MVC 3.
Have a look at my fork:
https://github.com/JonCanning/MvcIntegrationTestFramework/
I realize this is not the answer you're looking for but Selenium or Watin may be of use to you as an alternative to the Integration Test Framework.
Selenium will let you record tests as nUnit code so you can integrate with your existing test projects etc. Then your test can validate the DOM similarly to the Integration Test Framework. The advantage is Selenium tests can be executed with various different browsers.
Key caveat is that Selenium needs your app to be deployed on a web server, not sure if that's a show stopper for you.
I thought I would share my experiences with using MvcIntegrationTestFramework in an ASP.NET MVC 4 project. In particular, the ASP.NET MVC 4 project was a Web Role for a Windows Azure Cloud Service.
Although the example project from Jon Canning's fork worked for me (although I did change the System.Web.Mvc assembly from 3.0.0.0 to 4.0.0.0, which required a bunch of editing in the web.config file to get the tests to run and pass), I got an error whenever I tried to run the same tests against an Azure ASP.NET MVC 4 Web Role project. The error was:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
The inner exception was:
System.InvalidOperationException: This method cannot be called during the application's pre-start initialization phase.
I started wondering how an Azure Web Role project based on ASP.NET MVC 4 was different to a normal ASP.NET MVC 4 project, and how such a difference would cause this error. I did a bit of searching on the web but didn't come across anybody trying to do the same thing that I was doing. Soon enough I managed to realise that it was to do with the Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener. Part of the role of this class seems to be to ensure that the web role is running in a hosted service or the Development Fabric (you'll see a message to this effect if you switch the startup project from the cloud service project to the web role project inside a cloud service solution, and then try to debug).
The solution? I removed the corresponding listener from the Web.config file of my Web Role project:
<configuration>
...
<system.diagnostics>
<trace>
<listeners>
<!--Remove this next 'add' element-->
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics"> <filter type="" /> </add>
</listeners>
</trace>
</system.diagnostics>
...
</configuration>
I was then able to run integration tests as normal against my Web Role project. I did, however, add the listener to the Web.Debug.config and Web.Release.config transformation files so that everything was still the same for normal deploying and debugging.
Maybe that will help somebody looking to use the MvcIntegrationTestFramework for Azure development.
EDIT
I just realised that this solution might be a bit of a 'hack' because it might not let you do integration testing on application code that relates to Azure components (e.g. the special Azure caching mechanisms perhaps). That said, I haven't come across any issues to do with this yet, although I also haven't really written that many integration tests yet either...
I used Jon Canning's updated version (https://github.com/JonCanning/MvcIntegrationTestFramework/) and it solved my problem very well for controller methods that only accept value types and strings, but did not work for those that accepted classes.
It turns out there was an issue with the code for the updated MvcIntegrationTestFramework.
I figured out how to fix it, but don't know where else to post the solution, so here it is:
A simple sample to show how it works is:
[TestMethod]
public void Account_LogOn_Post_Succeeds()
{
string loginUrl = "/Account/LogOn";
appHost.Start(browsingSession =>
{
var formData = new RouteValueDictionary
{
{ "UserName", "myusername" },
{ "Password", "mypassword" },
{ "RememberMe", "true"},
{ "returnUrl", "/myreturnurl"},
};
RequestResult loginResult = browsingSession.Post(loginUrl, formData);
// Add your test assertions here.
});
}
The call to browsingSession.Post would ultimately cause the NameValueCollectionConversions.ConvertFromRouteValueDictionary(object anonymous) method to be called, and the code for that was:
public static class NameValueCollectionConversions
{
public static NameValueCollection ConvertFromObject(object anonymous)
{
var nvc = new NameValueCollection();
var dict = new RouteValueDictionary(anonymous); // ** Problem 1
foreach (var kvp in dict)
{
if (kvp.Value == null)
{
throw new NullReferenceException(kvp.Key);
}
if (kvp.Value.GetType().Name.Contains("Anonymous"))
{
var prefix = kvp.Key + ".";
foreach (var innerkvp in new RouteValueDictionary(kvp.Value))
{
nvc.Add(prefix + innerkvp.Key, innerkvp.Value.ToString());
}
}
else
{
nvc.Add(kvp.Key, kvp.Value.ToString()); // ** Problem2
}
}
return nvc;
}
Then there was two problems:
The call to new RouteValueDictionary(anonymous) would cause the "new" RouteValueDictionary to be created, but instead of 4 keys, there are only three, one of which was an array of 4 items.
When it hits this line: nvc.Add(kvp.Key, kvp.Value.ToString(), the kvp.Value is an array, and the ToString() gives:
"System.Collections.Generic.Dictionary'2+ValueCollection[System.String,System.Object]"
The fix (to my specific issue) was to change the code as follows:
var dict = anonymous as RouteValueDictionary; // creates it properly
if (null == dict)
{
dict = new RouteValueDictionary(anonymous);
}
After I made this change, then my model class would properly bind, and all would be well.

Why doesn't Console.Readline work but Console.Readline() does?

How do you use Console.Readline in F#? Unlike Console.Writeline, it isn't being honored when I call it.
If you use
let s = Console.ReadLine
you are only building a delegate that points to the ReadLine function. You need to say
let s = Console.ReadLine()
to actually execute the function. This is just like C# syntax, except type inference means you don't get a compiler warning.
What do you mean by "it isn't being honored"? Here's a small console app I've just written in VS2010b1, and it works fine:
open System
let line = Console.ReadLine()
Console.WriteLine("You wrote {0}", line)
// Just to make it pause
let unused = Console.ReadLine()
Are you trying to run the code from F# Interactive within Visual Studio? If so, that may be the issue, as Brian's post explains.
However, I haven't seen the same problem when using F# Interactive from the command line. Here's a complete transcript of a session:
Microsoft F# Interactive, (c) Microsoft Corporation, All Rights Reserved
F# Version 1.9.6.16, compiling for .NET Framework Version v4.0.20506
Please send bug reports to fsbugs#microsoft.com
For help type #help;;
> open System;;
> let line = Console.ReadLine();;
Hello world
val line : string = "Hello world"
Running Brian's looping code from F# Interactive didn't show the same problem.
Bottom line: It seems like this is broken in F# Interactive in Visual Studio, but not when running interactively from the command line or in a full console app.
I don't have a Beta1 box handy, but I know that in the past we've had a bug where ReadLine() would see the background commands that communicate between the interactive UI and the background process that runs your F# code. It may be interesting to investigate what
let Foo max =
let rec Loop i =
if i < max then
let line = System.Console.ReadLine()
printfn "line = %s" line
Loop (i+1)
Loop 1
Foo 12
prints when you highlight it and 'Send to Interactive'. I think possibly you'll see a few unexpected interesting lines, followed by lines you type into the window.
// is the right way if you're not wanting to use a return of anything typed into readline
Console.ReadLine() |> ignore

Resources