0

我有一个相当大的项目,使用 F# 编写的 Azure Function v2。我在 C# 中创建了一个库,在构造函数中我可以传递一个ILogger log. 如果我只在 Azure Function 项目中添加这个库,每个函数都会返回一个错误。

Microsoft.Azure.WebJobs.Host:无法将参数“日志”绑定到 ILogger 类型。确保绑定支持参数类型

在此处输入图像描述

在 F# 中,我尝试添加

[<FunctionName("organization")>]
let public organization
    ( [<HttpTrigger(AuthorizationLevel.Function, "post", Route = "organisations/{organisationId}")>]
        request : HttpRequestMessage,
        organisationId : string,
        executionContext : ExecutionContext,
        log : ILogger) =

      let PaymentGateway = PaymentGateway(Environment.GetEnvironmentVariable "Api_Secret_Key", log)

      ...

我在GitHub 上看到了一些帖子,或者其他人有同样问题的其他帖子。显然,解决方案是将 Azure 函数从 v2 更新到 v3,但我现在不能这样做。

有什么解决办法吗?

更新

.fsproj是_

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <AzureFunctionsVersion>v2</AzureFunctionsVersion>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Update="FSharp.Core" Version="4.6.2" />
  </ItemGroup>
</Project>
4

2 回答 2

1

不管怎样,你的fs确实有问题。我在这里发布了可以成功触发的函数的文件和代码:

这是我的函数应用程序的结构:

在此处输入图像描述

这是我的 .fsproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="HttpTrigger.fs" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.3" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </Content>
  </ItemGroup>
</Project>

这是我的触发文件 HttpTrigger.fs:

namespace Company.Function

open System
open System.IO
open Microsoft.AspNetCore.Mvc
open Microsoft.Azure.WebJobs
open Microsoft.Azure.WebJobs.Extensions.Http
open Microsoft.AspNetCore.Http
open Newtonsoft.Json
open Microsoft.Extensions.Logging

module HttpTrigger =
    // Define a nullable container to deserialize into.
    [<AllowNullLiteral>]
    type NameContainer() =
        member val Name = "" with get, set

    // For convenience, it's better to have a central place for the literal.
    [<Literal>]
    let Name = "name"

    [<FunctionName("HttpTrigger")>]
    let run ([<HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)>]req: HttpRequest) (log: ILogger) =
        async {
            log.LogInformation("F# HTTP trigger function processed a request.")

            let nameOpt = 
                if req.Query.ContainsKey(Name) then
                    Some(req.Query.[Name].[0])
                else
                    None

            use stream = new StreamReader(req.Body)
            let! reqBody = stream.ReadToEndAsync() |> Async.AwaitTask

            let data = JsonConvert.DeserializeObject<NameContainer>(reqBody)

            let name =
                match nameOpt with
                | Some n -> n
                | None ->
                   match data with
                   | null -> ""
                   | nc -> nc.Name
            
            let responseMessage =             
                if (String.IsNullOrWhiteSpace(name)) then
                    "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                else
                    "Hello, " +  name + ". This HTTP triggered function executed successfully."

            return OkObjectResult(responseMessage) :> IActionResult
        } |> Async.StartAsTask

工作正常,成功的日志:

在此处输入图像描述

这是我创建和运行 F# 函数的步骤:

1.在cmd中运行这两个命令:

dotnet new --install Microsoft.Azure.WebJobs.ItemTemplates

dotnet new --install Microsoft.Azure.WebJobs.ProjectTemplates

2.创建函数应用:

dotnet new func --language F# --name FunctionsInFSharp

3.创建触发器:

dotnet new http --language F# --name HttpTrigger

4.添加触发器编译:

<Compile Include="HttpTrigger.fs" />

请将上述代码添加到 .fsproj 文件中的 ItemGroup 中。

5.更改模板,将这些从无更改为内容:

在此处输入图像描述

我给出的只是一个简单的例子,说明如何成功触发F#函数,请尝试一下,告诉我是否可以解决。:)

于 2020-06-02T07:57:35.970 回答
0

经过一周的测试和更改,我找到了一个不理想的解决方案,但它正在工作。

在函数中,我这样定义logInfo

let logInfo : Action<string> = new Action<string>(fun (x: string) -> log.LogInformation(x))

在我的 C# 库中,我删除了对的任何引用Microsoft.Extensions.Logging并将其替换为:

private Action<string> _logger;
public PaymentGateway(string apiKey, Action<string> logger) {
    _logger = logger;
}

至少,我的组件中有日志。我不喜欢这个解决方案,但这是我可以用 F# 做的。

于 2020-06-03T17:11:21.520 回答