【问题标题】:Amazon Lambda in C# - JsonReaderExceptionC# 中的 Amazon Lambda - JsonReaderException
【发布时间】:2017-07-14 07:20:12
【问题描述】:

我正在尝试用 C# 编写 AWS Lambda 函数。我有 AWS Toolkit for Visual Studio 2015。我使用 AWS Lambda 项目 (.Net Core) 创建了一个项目,然后选择了 Empty Function 选项。这给了我以下代码:

UPDATE & ANSWER 02/24/17 - 标记为答案的评论是有用的知识,但对我来说不是实际答案。 @PavelSafronov 在那个答案中的评论起到了作用。我要么什么都没传递(并得到错误),要么我认为它希望我以 JSON 格式提供信息,所以我输入 { "input": "Some string" } 并仍然得到错误。现在我刚刚传入了“Some string”,它起作用了。 然而,就我而言,这似乎是一个错误。 string 默认是 nullable 并且代码由 Amazon 编写 甚至假设它可能是 input?.ToUpper() 的虚拟地址,?. 正在检查 null

注意: 我添加了 LambdaLogger.Log 行和 Constructor 以查看我得到的位置

using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.Json;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(JsonSerializer))]

namespace AWSLambdaTest1 {

  public class Function {

    public Function() {
      LambdaLogger.Log("Within the Constructor");
    }

    public string KevinsTestFunction(string input, ILambdaContext context) {
      LambdaLogger.Log("Within the KTF");
      return input?.ToUpper();
    }

  }
}

输出屏幕和解决方案资源管理器说:

Errors in C:\Test Projects\AWSLambda1\AWSLambda1\AWSLambda1.xproj
  Unable to resolve 'Amazon.Lambda.Core (>= 1.0.0)' for '.NETCoreApp,Version=v1.0'.

但是,这将毫无疑问地构建并发布到 AWS。我什至可以调用它返回以下内容 - 这是我的主要问题

{
  "errorType" : "JsonReaderException",
  "errorMessage" : "Unexpected character encountered while parsing value: {. Path '', line 1, position 1.",
  "stackTrace"   : [
    "at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType)",
    "at Newtonsoft.Json.JsonTextReader.ReadAsString()",
    "at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)",
    "at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)",
    "at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)",
    "at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)",
    "at lambda_method(Closure , Stream , Stream , ContextInfo )"
  ]
}

日志文件显示Constructors 日志消息到达那里,但不是实际的KevingsTestFunction 日志消息。

附带说明,我可以通过将以下内容添加到我的 project.json 文件中来消除 Unable to resolve 'Amazon.Lambda.Core (>= 1.0.0)' for '.NETCoreApp,Version=v1.0' 错误:

"runtimes": {
  "win10-x64": {},
  "win81-x64": {},
  "win8-x64": {},
  "win7-x64": {}
}

这在 Windows 机器上是有道理的,在亚马逊上就没有那么多了。我需要一些不同的runtime(s)吗?

该更改并未更改 JsonReaderException 异常。

我尝试添加"Linux": {},但这也没有改变。

我什至尝试将 NuGet 包 Microsoft.NETCore.App1.0.0 更新为 1.1.0,但也没有任何效果,甚至返回到 1.0.1

我认为他们给你的默认示例会起作用,但我错了。 Amazon.Lambda.Serialization.Json.JsonSerializer 属性似乎存在问题。是否可以只使用NewtonSoft

【问题讨论】:

  • 回复:“但是,就我而言,这似乎是一个错误。默认情况下,字符串可以为空......” - 未引用的 null 是有效的 JSON,如果通过了进入一个需要字符串的函数,字符串参数将为空。这可以通过使用 AWS Lambda 控制台并指定 null 作为测试 JSON 有效负载来验证,但 不是 AWS VS Toolkit,因为 Toolkit 将不带引号的文本视为字符串(为方便起见)并引用它在将其传递给 Lambda 之前。

标签: c# amazon-web-services aws-lambda


【解决方案1】:

帕维尔·萨弗罗诺夫 -

是的,如果您的 Lambda 函数入口点是:

public string KevinsTestFunction(string input, ILambdaContext context) {

那么你可以输入的字符串是:

"{ \"input\": \"Something\" }"

您还可以将 Lambda 函数入口点更改为:

public string KevinsTestFunction(JObject input, ILambdaContext context) {

然后你可以像这样输入一个json对象:

{ "input": "Something" }

如果您不期望任何输入而只是轮询 SQS 队列或 DynamoDb 表,那么您可以将 Lambda 函数的入口点更改为:

public string KevinsTestFunction(ILambdaContext context) {

许多变体可供玩弄。


现在根据原始问题中的更新,默认情况下,AWS Web 控制台测试区域将为您设置默认测试数据以发送到您的 Lambda 函数。该默认测试数据是一个 JSON 对象。如前所述,这与通过 AWS 开发工具包通过 Visual Studio 提供的 C# Lambda(接受字符串输入)的默认模板不一致。也许这是一个内置的绊脚石(功能),迫使我们遇到这个问题,把我们的头发拉出来,然后意识到函数处理程序的多功能性......

【讨论】:

  • 我转义了输入字符串,但它不起作用。我还尝试使用 JObject(而不是字符串输入),但 Step 函数无法将输入的 Json 字符串转换为 JObject。 @Pavel Safronov,你有什么意见吗?
  • 您能否提供传递给 Lambda 函数的原始字符串(以及所有转义字符等)?
  • 这是为我做的。
【解决方案2】:

更新代码:

public string KevinsTestFunction(string input, ILambdaContext context) {
  LambdaLogger.Log("Within the KTF");
  return input?.ToUpper();
}

到:

public string KevinsTestFunction(IDictionary input, ILambdaContext context) {
  LambdaLogger.Log("Within the KTF");
  return input["input"]?.ToUpper();
}

别忘了

using System.Collections;

【讨论】:

    【解决方案3】:

    我在 C# 中使用 AWS Lambda 的经验有点有限,但是当输入(如果您从控制台触发函数,则为“测试”数据)不是实际的 JSON 格式时,我会遇到这种错误。最好的办法可能是为您的测试目的创建一个虚拟输入类,然后为 lambda 函数提供等效的 JSON 数据以使其正确序列化。

    至于您的 project.json,我之前不需要为 AWS Lambda 添加运行时部分。如果这样做,则需要从此列表中选择相关的运行时: https://docs.microsoft.com/en-us/dotnet/articles/core/rid-catalog

    如果您觉得有用,这里还有一个示例 project.json 文件: https://gist.github.com/TAGray/8cc812065c3b6abcd732b7f6a3bda92a

    希望对您有所帮助。

    【讨论】:

    • 在发布成功的结果窗口中,有一个Test Function |配置 |事件源 |日志选项 - 我在测试功能上,我没有在示例请求中或在它下面的框中输入任何内容。我单击 Invoke 并收到 JsonReaderException 消息。我输入了{ "input": "Something" } 的有效 JSON 并得到了相同的消息。
    • 我创建了一个与我描述的相同的新项目,除了这次我使用了“With Tests”。确定“测试功能”选项可能只是一个真正的测试功能(在这里抓住稻草。)在这个新项目中使用非测试功能,同样的错误JsonReaderException。我无法使用实际测试功能的完整路径,因为它实际上不是包的一部分。我没有通过命令行 (AWS CLI) 执行任何操作
    • 问题中的函数需要一个字符串,因此您应该传入一个带引号的字符串。如果你的函数需要一个复杂的类型,你可以传入 JSON 对象。
    猜你喜欢
    • 2018-03-17
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 2019-01-11
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    相关资源
    最近更新 更多