【问题标题】:Azure Function - ServiceBusTrigger - Exception Binding MessageAzure 函数 - ServiceBusTrigger - 异常绑定消息
【发布时间】:2019-10-22 05:30:56
【问题描述】:

我有一个订阅 Azure 服务总线队列的 Azure 函数 - 但是在函数能够触发异常之前,运行时会在它到达我的任何代码之前抛出异常。

Exception while executing function: <functionName>. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'message'. System.Private.CoreLib: Unable to translate bytes [9A] at index 60 from specified code page to Unicode.

在这种情况下,我无法控制传入的消息(它实际上是从 Azure DevOps 订阅发送的),因此我需要能够使函数更加灵活,以免引发此异常。

我的函数如下所示:

[FunctionName("FunctionName")]
public static async Task Run(
    [ServiceBusTrigger("Queue", Connection = "ConnectionString")] byte[] message)

我看到其他问题建议不要使用MessageBrokeredMessage 对象,而是使用byte[](并编写您自己的编码来处理该问题)但这对我不起作用.运行时似乎仍在尝试并未能在消息到达我的函数之前对其执行某些操作。

如何避免这个问题?


我将保留这个问题,因为我还没有找到解决这个问题的方法 - 但是我现在已经看到了如何在我的实例中解决它。我一直在努力处理的消息是由AzureDevOps ServiceHooks 传递的消息。如果我进入设置(在创建或编辑时)这里找到的服务挂钩 -> https://.visualstudio.com//_settings/serviceHooks

我错过了一个复选框。为了使 Azure 函数能够处理消息,需要选中此复选框。 IE。您想作为非序列化字符串发送。这一定是因为在我的函数和队列之间的任何客户端都无法处理 .Net 序列化消息。

Tl;Dr -> 如果您有这个问题,请确保选择了上面的这个选项

GitHub Issue跟踪问题

【问题讨论】:

  • 你试过string message而不是byte[] message吗?
  • 1.你使用什么版本的函数? 2. 发送此消息的 ASB 客户端版本是什么,它是如何发送的(理想情况下是要共享的代码)?
  • @chris string message 不幸地做了同样的事情。 @SeanFeldman Microsoft.NET.Sdk.Functions 版本是 1.0.27 - 我相信我正在运行最新版本的功能(来自 VS2019)。此外,我没有发送消息 - 它的发送者:docs.microsoft.com/en-us/azure/devops/service-hooks/…

标签: encoding .net-core azure-devops azure-functions azureservicebus


【解决方案1】:

问题是函数库在决定是否解码时查看消息类型而不是函数中指定的类型。由于 Devops 以 application/json 类型发送消息,因此库正在尝试使用 UTF8 对其进行解码。

目前,选择“作为非序列化字符串发送”是一种有效的解决方法。可以在 Github 上跟踪该问题: https://github.com/Azure/azure-webjobs-sdk/issues/2234

相关代码(Microsoft.Azure.WebJobs.ServiceBus.Triggers.UserTypeArgumentBindingProvider)

 private static TInput GetBody(Message message, ValueBindingContext context)
        {
            if (message.ContentType == ContentTypes.ApplicationJson) //This is looking at the message type
            {
                string contents;

                contents = StrictEncodings.Utf8.GetString(message.Body);

                try
                {
                    return JsonConvert.DeserializeObject<TInput>(contents, Constants.JsonSerializerSettings);
                }
                catch (JsonException e)
                {
                    // Easy to have the queue payload not deserialize properly. So give a useful error. 
                    string msg = string.Format(
    @"Binding parameters to complex objects (such as '{0}') uses Json.NET serialization. 
    1. Bind the parameter type as 'string' instead of '{0}' to get the raw values and avoid JSON deserialization, or
    2. Change the queue payload to be valid json. The JSON parser failed: {1}
    ", typeof(TInput).Name, e.Message);
                    throw new InvalidOperationException(msg);
                }
            }
            else
            {
                return message.GetBody<TInput>();
            }
        }
    }

【讨论】:

    【解决方案2】:

    所以在新世界(.net 5 功能应用程序)。我们从[FunctionName("FunctionName")]移到[Function("FunctionName")]

    此外,您不能再使用“消息”或字节[]。只能是字符串!

     public async Task Run([ServiceBusTrigger(topicName, SubscriberName, Connection= %conn% )] string messageText, string id,  FunctionContext executionContext)
    

    现在的魔力在于 FunctionContext

    可以通过这种方式获取消息属性:

    executionContext.BindingContext.BindingData.Where(x => x.Key =="UserProperties")
    

    【讨论】:

    • 非常有用的信息是否有一些来源可以让我了解有关这些更改的更多信息?
    猜你喜欢
    • 1970-01-01
    • 2019-09-30
    • 2020-08-27
    • 2018-03-23
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    相关资源
    最近更新 更多