从Azure Services上的服务总线处理程序接收事件网格

时间:2019-11-29 01:20:05

标签: .net azure azureservicebus azure-eventgrid

我在事件网格上发送事件。我可以看到他们到达了天蓝色仪表板

            NomeEmailChange yay = new NomeEmailChange
            {
                Nome = "cesco",
                Email = "cesco"
            };

            var primaryTopicKey = _config["EventGridConfig:AcessKey"];
            var primaryTopic = _config["EventGridConfig:Endpoint"];

            var primaryTopicHostname = new Uri(primaryTopic).Host;

            var topicCredentials = new TopicCredentials(primaryTopicKey);
            var client = new EventGridClient(topicCredentials);

            var id = Guid.NewGuid().ToString();
            var hey = new List<EventGridEvent>
            {
                new EventGridEvent()
                {
                    Id = id,
                    EventType = "cesco-cesco",
                    Data = (yay),
                    EventTime = DateTime.Now,
                    Subject = "MS_Clientes",
                    DataVersion = "1.0",
                }
            };
            ;
            client.PublishEventsAsync(primaryTopicHostname, hey);

然后,我创建了一个事件网格订阅。我可以确认到达事件网格订阅的事件网格消息。

在另一个项目中,我正在订阅下面的服务总线。它可以很好地处理直接发送到总线的消息。

        public static IServiceCollection AddBus(this IServiceCollection services, IConfiguration configuration,
            IHostingEnvironment env)
        {
            services.AddMassTransit(x => { x.AddConsumer<NomeEmailChangeConsumer>(); });
            services.AddSingleton(provider => Bus.Factory.CreateUsingAzureServiceBus(cfg =>
            {
                var keyName = "RootManageSharedAccessKey";
                var busName = configuration["ServiceBus:Name"];
                var secret = configuration["ServiceBus:Secret"];
                var host = cfg.Host(
                    "Endpoint=sb://" + busName + ".servicebus.windows.net/;" +
                    "SharedAccessKeyName=" + keyName + ";" +
                    "SharedAccessKey=" + secret,
                    z =>
                    {
                        TokenProvider
                            .CreateSharedAccessSignatureTokenProvider(keyName, secret);
                    });
                cfg.UseExtensionsLogging(provider.GetService<ILoggerFactory>());
                cfg.ReceiveEndpoint(host, configuration["ServiceBus:Topic"],
                    e => { e.Consumer<NomeEmailChangeConsumer>(provider); });
            }));
            services.AddSingleton<IPublishEndpoint>(provider => provider.GetRequiredService<IBusControl>());
            services.AddSingleton<ISendEndpointProvider>(provider => provider.GetRequiredService<IBusControl>());
            services.AddSingleton<IBus>(provider => provider.GetRequiredService<IBusControl>());
            services.AddScoped(provider => provider.GetRequiredService<IBus>().CreateRequestClient<NomeEmailChange>());
            services.AddSingleton<IHostedService, BusService>();
            return services;
        }

所有功能都应该可以正常工作,但是在另一个项目上,当消息到达时,我会收到以下错误消息

fail: MassTransit.Messages[0]
      R-FAULT sb://sbacompanharreldev.servicebus.windows.net/bff-queue 9ade19ec-238c-4c08-8e03-28bac695ea7b No deserializer was registered for the message content type: application/json; charset=utf-8. Supported content types include application/vnd.masstransit+json, application/vnd.masstransit+bson, application/vnd.masstransit+xml
System.Runtime.Serialization.SerializationException: No deserializer was registered for the message content type: application/json; charset=utf-8. Supported content types include application/vnd.masstransit+json, application/vnd.masstransit+bson, application/vnd.masstransit+xml
   at MassTransit.Serialization.SupportedMessageDeserializers.Deserialize(ReceiveContext receiveContext)
   at MassTransit.Pipeline.Filters.DeserializeFilter.Send(ReceiveContext context, IPipe`1 next)
   at GreenPipes.Filters.RescueFilter`2.GreenPipes.IFilter<TContext>.Send(TContext context, IPipe`1 next)

2 个答案:

答案 0 :(得分:5)

根据建议,您必须编写自定义解串器。在我的实现中,我对如何处理MassTransit包进行了几处更改。

首先,您必须为不同的内容类型注册反序列化器:

  1. 例如,如果您的消息来自MassTransit发布者,它将是默认消息ContentType(在C#中):foo()[0] = "hi";
  2. 如果您的消息来自ServiceBus队列/主题,通常为JsonMessageSerializer.JsonContentType

以下代码显示如何注册反序列化器以及如何设置接收端点。与您的方法相比,差异之一是我使用了连接字符串,因此不需要SAS令牌部分。

"application/json"

我使用https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html将消息传递到EventGrid,EventGrid将消息转发到SB队列,在下面您可以看到运行此代码的结果:

message simulator

用于事件网格消息的反序列化器以及完整代码,可以在Github上找到:enter image description here,也可以在我对其他问题的回答中找到。

答案 1 :(得分:0)

MassTransit使用的消息信封用于反序列化内容。 您将需要创建并注册自定义序列化程序,以允许MassTransit提取和处理您的消息。有关更多信息,请参见Interoperability文档。创建自定义序列化程序后,即可使用configuration API注册。