visual-studio - F# docker 应用程序:标有“EntryPointAttribute”属性的函数必须是最后一个文件中的最后一个声明......?
问题描述
通过从头开始创建一个新项目,可以轻松地重现该问题。
Visual Studio 版本为 V15.7.5。我创建了一个新的 F# .Net core 2.1 应用程序,支持 docker (Linux)。但是,它得到了以下错误。
标有“EntryPointAttribute”属性的函数必须是编译序列中最后一个文件中的最后一个声明。
以下是Dockerfile
.
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 64890
EXPOSE 44390
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY WebApplication8/WebApplication8.fsproj WebApplication8/
RUN dotnet restore WebApplication8/WebApplication8.fsproj
COPY . .
WORKDIR /src/WebApplication8
RUN dotnet build WebApplication8.fsproj -c Release -o /app
FROM build AS publish
RUN dotnet publish WebApplication8.fsproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "WebApplication8.dll"]
以下是Program.fs
namespace WebApplication8
open System
open System.Collections.Generic
open System.IO
open System.Linq
open System.Threading.Tasks
open Microsoft.AspNetCore
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.Configuration
open Microsoft.Extensions.Logging
module Program =
let exitCode = 0
let CreateWebHostBuilder args =
WebHost
.CreateDefaultBuilder(args)
.UseStartup<Startup>();
[<EntryPoint>]
let main args =
CreateWebHostBuilder(args).Build().Run()
exitCode
.fsproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
<UserSecretsId>b379991e-83d8-444e-b888-62e9ac139864</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<Compile Include="Controllers/ValuesController.fs" />
<Compile Include="Startup.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<None Include="Dockerfile" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
完全错误,
1>----- 构建开始:项目:docker-compose,配置:调试任何 CPU ------ 1>docker ps --filter "status=running" --filter "name=dockercompose15479956486365536117_webapplication8_" --format {{.ID}} -n 1 1>e95714bd0022 1>docker exec -i e95714bd0022 /bin/bash -c “如果 PID=$(pidof -x dotnet); 然后杀死 $PID;fi” 1>c:\source\repos\WebApplication8\WebApplication8\WebApplication8.fsproj:警告 NU1701:使用 '.NETFramework,Version=v4.6.1' 而不是项目目标框架恢复了包 'System.Linq.Queryable 4.0.1' '.NETCoreApp,版本 = v2.1'。此软件包可能与您的项目不完全兼容。 1>c:\source\repos\WebApplication8\WebApplication8\Program.fs(22,9):错误 FS0433:标有“EntryPointAttribute”属性的函数必须是编译序列中最后一个文件中的最后一个声明。 1>完成构建项目“WebApplication8.fsproj”——失败。 ========== 构建:0 成功或最新,1 失败,0 跳过 ==========
VS生成的start.fs
namespace WebApplication8
open System
open System.Collections.Generic
open System.Linq
open System.Threading.Tasks
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.AspNetCore.HttpsPolicy;
open Microsoft.AspNetCore.Mvc
open Microsoft.Extensions.Configuration
open Microsoft.Extensions.DependencyInjection
type Startup private () =
new (configuration: IConfiguration) as this =
Startup() then
this.Configuration <- configuration
// This method gets called by the runtime. Use this method to add services to the container.
member this.ConfigureServices(services: IServiceCollection) =
// Add framework services.
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1) |> ignore
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
member this.Configure(app: IApplicationBuilder, env: IHostingEnvironment) =
if (env.IsDevelopment()) then
app.UseDeveloperExceptionPage() |> ignore
else
app.UseHsts() |> ignore
app.UseHttpsRedirection() |> ignore
app.UseMvc() |> ignore
member val Configuration : IConfiguration = null with get, set
VS生成的value.fs
namespace WebApplication8.Controllers
open System
open System.Collections.Generic
open System.Linq
open System.Threading.Tasks
open Microsoft.AspNetCore.Mvc
[<Route("api/[controller]")>]
[<ApiController>]
type ValuesController () =
inherit ControllerBase()
[<HttpGet>]
member this.Get() =
let values = [|"value1"; "value2"|]
ActionResult<string[]>(values)
[<HttpGet("{id}")>]
member this.Get(id:int) =
let value = "value"
ActionResult<string>(value)
[<HttpPost>]
member this.Post([<FromBody>] value:string) =
()
[<HttpPut("{id}")>]
member this.Put(id:int, [<FromBody>] value:string ) =
()
[<HttpDelete("{id}")>]
member this.Delete(id:int) =
()
解决方案
.fsproj 中的 UserSecretsId 标记导致了问题,因为 .net 核心编译器在错误的位置为其生成代码。解决方案是删除标签并将其添加到单独的 assemblyinfo.fs 文件中:
module Your.Namespace.AssemblyInfo
open Microsoft.Extensions.Configuration.UserSecrets
[<assembly: UserSecretsIdAttribute(“b379991e-83d8-444e-b888-62e9ac139864”)>]
do()
有关问题和解决方法的更详细描述,请参阅本文:使 ASP.NET Core 用户机密在 F# 项目中工作
推荐阅读
- azure-iot-hub - Azure IotHub 路由不起作用
- wpf - 解决由于 dataBinding 而生成的 WPF 内存泄漏问题
- node.js - Google Sheet npm 包更新表与排序数据(Node.js)
- asynchronous - Mocha 测试异步函数,它没有显式返回一个承诺
- kubernetes - 如何从 POD 中获取运行 POD 的节点的主机名
- python - TypeError: <<: 'str' 和 'int' 的操作数类型不受支持
- python - 根据列表中的项目删除重复的嵌套列表
- c# - 图像未显示在 C# 的列表视图中
- ruby-on-rails - 在 iframe 中提供服务时,Rails 应用程序返回 422 响应(无法验证 CSRF 令牌真实性)
- java - Java Runtime.exec 使用 GZIP 返回 1