F# .NET Core 2.1 simple crud app: controllers don't get registered

Viewed 483

I am trying to use F# with .NET Core 2.1 to create a simple CRUD application but none of the controllers don't get registered. I see none of the controllers in Swagger and the controller themselves don't start.

I appreciate any help or hint.

Startup.fs

namespace SimpleCms

type Startup private () =
    let mutable configuration : IConfigurationRoot = null

    member this.Configuration
        with get () = configuration
        and private set (value) = configuration <- value

    new(env : IHostingEnvironment) as this =
        Startup()
        then 
            let builder =
                ConfigurationBuilder()
                    .SetBasePath(env.ContentRootPath)
                    .AddJsonFile("appsettings.json", optional = false, reloadOnChange = true)
                    .AddJsonFile(sprintf "appsettings.%s.json" env.EnvironmentName, optional = true)
                    .AddEnvironmentVariables()

            this.Configuration <- builder.Build()

    // This method gets called by the runtime. Use this method to add services to the container.
    member this.ConfigureServices(services : IServiceCollection) =

        services.AddLogging() |> ignore

        services.AddSwaggerGen(fun x ->
            x.SwaggerDoc("v1", new Info(Title = "SimpleCms", Version = "v1")) |> ignore)
            |> ignore

        services.AddMvcCore() |> ignore

        services.AddMvc() |> ignore

        let container =
            new Container(fun opt -> 

            opt.Scan(fun x -> 
                x.AssemblyContainingType(typeof<Startup>)
                x.Assembly("Dal")
                x.Assembly("Logic")
                x.WithDefaultConventions() |> ignore)

            opt.For<LiteDatabase>().Use(new LiteDatabase("Filename=database.db")) |> ignore

            opt.Populate(services) |> ignore)

        container.GetInstance<IServiceProvider>()

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    member this.Configure(app : IApplicationBuilder, env : IHostingEnvironment) =
        app.UseSwagger() |> ignore

        app.UseSwaggerUI(fun x ->
            x.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1") |> ignore) |> ignore

        app.UseMvc(fun x ->
            x.MapRoute("default", "{controller=Home}/{action=Index}") |> ignore) |> ignore

HomeController.fs

namespace SimpleCms.Controllers

open Microsoft.AspNetCore.Mvc

[<Route("")>]
type HomeController() =
    inherit Controller()

    [<Route("")>]
    [<HttpGet>]
    member this.Index() =
        Ok("Hello World!")

The complete code

Repo URL

1 Answers

Your problem is the IPostController interface. Remove that and Swagger will pick up the PostController.

For example:

[<Route("api/[controller]")>]
[<ApiController>]
type PostController(logic : IPostLogic) =
    inherit Controller()
    member this.logic = logic

        [<Route("")>]
        [<HttpGet>]
        member this.GetAll() = 
            this.logic.GetAll()

//etc

Which makes Swagger show this:

enter image description here

Side Note: For ASP.NET Core 2.1 and above, you shouldn't be specifying the version of the Microsoft.AspNetCore.All package, your fsproj file should contain this instead:

<PackageReference Include="Microsoft.AspNetCore.All" />

Which in turn means you should be using version 2.1.1 of Microsoft.Extensions.Logging.Debug.

Finally, you are using a really old version of Swashbuckle.AspNetCore. I suggest you upgrade that too.

Related