Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
290 views
in Technique[技术] by (71.8m points)

Asp.Net Core problem with Views and static files (F#)

I've been trying to create a very simple MVC project in F#. Here's a brief explanation of what I've done and I'd appreciate any help with it.

  • I created a new "ASP .NET Core Web Application" using VS 2019 template for F#.
  • Then I selected "ASP.NET Core Empty", ASP.NET Core 5.0.
  • I added a few files to the project in order to make the structure look as follows:
/ Root
  | appsettings.json
  | Views
     | Home
         | Index.cshtml // added as "Content", "Do not copy"
  HomeController.fs
  Startup.fs
  Program.fs

The controller is very simple:

type HomeController() =
    inherit Controller()

    this.Index() =
        this.View()

Then, when I launch my app, I get error:

InvalidOperationException: The view 'Index' was not found. The following locations were searched:
/Views/Home/Index.cshtml
/Views/Shared/Index.cshtml

So even though my cshtml file is there, it can't be found by the runtime.

I made sure "UseStaticFiles" is enabled in the Startup class:

type Startup() =
    member __.ConfigureServices(services) : unit =
        services.AddControllersWithViews() |> ignore

    member __.Configure(app, env) : unit =
        // env.ContentRootFileProvider.Root is set to my Root folder
        app.UseStaticFiles()   |> ignore
        app.UseRouting()       |> ignore
        app.UseAuthorization() |> ignore
        app.UseEndpoints(fun endpoints ->
            endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}") |> ignore
        ) |> ignore

Going further

I tried walking the problem around and read the content of cshtml manually and return it as string

type HomeController() =
    inherit Controller()

    member this.ManualIndex() =
        let html = System.IO.File.ReadAllText("/Views/Index.cshtml")
        this.Content(html, "text/html")

and it worked, but from the HTML I still can't refer to any other static files, like css or js. I also tried creating wwwroot directory and putting my static content there, but then didn't help either.

question from:https://stackoverflow.com/questions/65943337/asp-net-core-problem-with-views-and-static-files-f

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It turned out that F# version of the MVC project differs slightly from its C# counterpart, while I had assumed that it's only a matter of syntax.

In order for Razor to work in an F# project, an extra NuGet package is required: Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation. Then in Startup class an extension is needed (AddRazorRuntimeCompilation):

    member this.ConfigureServices(services: IServiceCollection) =
        services.AddControllersWithViews().AddRazorRuntimeCompilation() |> ignore
        services.AddRazorPages() |> ignore

I haven't looked that much into it, but I guess this has something about C#-F# interop. The razor's file extension (cshtml) suggests that it relies on C#. There might be some friction when attempting to use it from an F# project.

Moving forwards, I recommend creating an F# MVC project using dotnet templates. The one I needed can be created with the following command:

dotnet new mvc --language=F#

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...