Ошибки F # с ILogger в Azure Functions v2 - PullRequest
0 голосов
/ 26 мая 2020

У меня довольно большой проект с Azure функцией v2, написанной на F #. Я создаю библиотеку в C#, где в конструкторе я могу передать ILogger log. Если только я добавлю эту библиотеку в проект Azure Function, каждая функция вернет ошибку.

Microsoft. Azure .WebJobs.Host: невозможно привязать параметр 'log' к типу ILogger. Убедитесь, что тип параметра поддерживается привязкой

enter image description here

В 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)

      ...

I видел несколько сообщений, например, на 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>

Ответы [ 2 ]

0 голосов
/ 03 июня 2020

После solid недель тестов и изменений я нашел неидеальное решение, но оно работает.

В функции я определяю 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 #.

0 голосов
/ 02 июня 2020

Не смотря ни на что, ваша фс действительно проблематична c. Я разместил здесь файл и код функции, которая может быть успешно запущена:

Это структура моего приложения-функции:

enter image description here

This is my .fsproj:

  netcoreapp3. 1  v3     СохранитьНовые   PreserveNewest  Никогда     

А это мой файл триггера 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

Работает нормально, успешный журнал:

enter image description here

These is my step to create and run F# function:

1.Run these two command in cmd:

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

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

2.Create function app:

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

3.Create trigger:

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

4.Add trigger to compile:


Please add above code to ItemGroup in .fsproj file.

5.Change the template, change these from none to Content:

введите описание изображения здесь

Все, что я привел, - это простой пример того, как функция F # может быть успешно запущена, попробуйте и дайте мне знать, сможете ли вы решить эту проблему .:)

...