带有 HTTP 触发器的 Azure 函数无法从 JSON 有效负载绑定模型 (.NET 5 out-of-proc)

Azure Function with HTTP trigger fails to bind model from JSON payload (.NET 5 out-of-proc )

我是 运行 一个孤立的进程函数,无法从 JSON 有效负载绑定输入模型。

这是我的功能:

[Function("AddChip")]
public async Task<HttpResponseData> AddChip([HttpTrigger(AuthorizationLevel.Anonymous,
 "post", Route = "chip")] Chip chip, HttpRequestData req, FunctionContext executionContext)
{
            
    var logger = executionContext.GetLogger("Function1");
    logger.LogInformation("C# HTTP trigger function processed a request.");

    var result = await _chipService.UpsertChipAsync(chip);

    var response = req.CreateResponse(HttpStatusCode.OK);
    await response.WriteAsJsonAsync(result);
    return response;
}

这是我的 Chip class:

public class Chip
{
    public string Id {  get; set; }
    public double Balance { get; set; }
    public DateTime Created { get; set; }
    public DateTime Updated { get; set; }
}

但是当我从 Insomnia 调用它时,确保 Content-Type application/json header 设置为 body:

{
    "Id": "1",
    "Balance": 0,
    "Created": "2001-01-01T00:00:00",
    "Updated": "2001-01-01T00:00:00"
}

我收到一条错误消息,指出无法转换 chip 参数:

Microsoft.Azure.Functions.Worker.Diagnostics.Exceptions.FunctionInputConverterException: Error converting 1 input parameters for Function 'AddChip': Cannot convert input parameter 'chip' to type 'Models.Chip' from type 'Microsoft.Azure.Functions.Worker.GrpcHttpRequestData'.

我试过失败:

它似乎与 gRPC 有某种关系,因为错误引用 GrpcHttpRequestData

Microsoft documentation or this Rick van den Bosch post or even other Stack Overflow answers like 等不同来源暗示这应该有效,但实际上无效。

Azure Functions .NET 5 使用新的进程外模型,目前在模型绑定方面非常有限。

在 HTTP 请求的情况下,您的方法获得 HttpRequestData。请求正文或 URI 参数的任何映射都必须由您的代码完成。

正如 Stephen 在另一个答案中提到的,目前 .net 5 azure 函数(进程外模型)中没有完全成熟的模型绑定功能。您的请求负载在 HttpRequestData 实例的 Body 属性 中可用,您可以在您的函数中反序列化它。

下面的示例使用来自 System.Text.Json 命名空间的 JsonSerializer。

static JsonSerializerOptions SerializerOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    PropertyNameCaseInsensitive = true
};

[Function("AddChip")]
public async Task<HttpResponseData> AddChip(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "chip")] HttpRequestData req,
    FunctionContext executionContext)
{
    Chip chip = null;

    if (req.Body is not null)
    {
        chip = await JsonSerializer.DeserializeAsync<Chip>(req.Body, SerializerOptions);
    }

    var logger = executionContext.GetLogger("Function1");
    logger.LogInformation("C# HTTP trigger function processed a request for." + chip?.Id);

    var result = await _chipService.UpsertChipAsync(chip);

    var response = req.CreateResponse(HttpStatusCode.OK);
    await response.WriteAsJsonAsync(result);
    return response;
}