C# 使用BrokeredMessage从Azure服务总线队列(v1)反序列化强类型对象

C# 使用BrokeredMessage从Azure服务总线队列(v1)反序列化强类型对象,c#,azure,azure-functions,azureservicebus,azure-servicebus-topics,C#,Azure,Azure Functions,Azureservicebus,Azure Servicebus Topics,无论出于何种原因,我似乎无法弄清楚如何将对象从队列中拉出来,并将其反序列化回它作为的对象(一个AccountEventDTO) Azure函数已成功将对象放入队列: [FunctionName("AccountCreatedHook")] public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpReques

无论出于何种原因,我似乎无法弄清楚如何将对象从队列中拉出来,并将其反序列化回它作为的对象(一个AccountEventDTO

Azure函数已成功将对象放入队列:

[FunctionName("AccountCreatedHook")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req,
    TraceWriter log, [ServiceBus("topic-name", Connection = "BusConnectionString", EntityType = Microsoft.Azure.WebJobs.ServiceBus.EntityType.Topic)] IAsyncCollector<BrokeredMessage> accountCreatedTopic)
{
    var accountEvent = await req.Content.ReadAsAsync<AccountEventDTO>();

    if (accountEvent != null && accountEvent.Name != null)
    {
        // Serialization
        var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(accountEvent));
        var memoryStream = new MemoryStream(bytes, writable: false);
        var message = new BrokeredMessage(memoryStream) { SessionId = Guid.NewGuid().ToString() };

        await accountCreatedTopic.AddAsync(message);
        return req.CreateResponse(HttpStatusCode.OK, "Account successfully added to topic.");
    }

    return req.CreateResponse(HttpStatusCode.BadRequest, "Account was not formed well.");
}
[FunctionName("AccountCreatedSubscriber")]
public static void Run([ServiceBusTrigger("topic-name", "license-keys", Connection = "BusConnectionString")]BrokeredMessage accountEvent, ILogger log)
{
    // ERROR on this line during deserialization
    var account = accountEvent.GetBody<AccountEventDTO>();

    var accountAddedEvent = Mapper.Map<AccountEventDTO, AccountAddedEvent>(account);
    _accountHandler.Handle(accountAddedEvent);
    GenericLogger.AccountLogging(log, accountAddedEvent);
}
public class AccountEventDTO : IAccountEvent
{
    public string Name { get; set; }
    public string SugarId { get; set; }
    public string AccountSubTypeRaw { get; set; }
    public AccountType AccountType { get; set; } = AccountType.Customer;
    public AccountSubType? AccountSubType { get; set; } = null;
    public string Phone { get; set; }
    public string PhoneAlternate { get; set; }
    public string BillingAddressCity { get; set; }
    public string BillingAddressCountry { get; set; }
    public string BillingAddressPostalCode { get; set; }
    public string BillingAddressState { get; set; }
    public string BillingAddressStreet { get; set; }
    public string ShippingAddressCity { get; set; }
    public string ShippingAddressCountry { get; set; }
    public string ShippingAddressPostalCode { get; set; }
    public string ShippingAddressState { get; set; }
    public string ShippingAddressStreet { get; set; }
    public string Website { get; set; }
}
var jsonString = JsonConvert.SerializeObject(accountEvent);
var message = new BrokeredMessage(jsonString);
message.SessionId = Guid.NewGuid().ToString();
message.ContentType = "application/json";
var content = accountEvent.GetBody<string>();
var account = JsonConvert.DeserializeObject<AccountEventDTO>(content);

您正在使用
BrokeredMessage
(旧的Azure Service Bus客户端for.NET,)。当消息作为内存流发送时,必须使用相同的方法接收和反序列化消息<如果构造
BrokeredMessage
传入类型为
T
的对象,则code>GetBody将起作用


注意:下一代客户机()只使用字节数组(旧客户机的内存流)进行原始工作。如果这是一个新项目,建议使用该方法,而不是序列化类型。更多信息可以在GitHub上找到。

最终解决了这个问题,改变了我在发送端序列化消息的方式以及在接收端将消息向下拉的方式

发送序列化:

[FunctionName("AccountCreatedHook")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req,
    TraceWriter log, [ServiceBus("topic-name", Connection = "BusConnectionString", EntityType = Microsoft.Azure.WebJobs.ServiceBus.EntityType.Topic)] IAsyncCollector<BrokeredMessage> accountCreatedTopic)
{
    var accountEvent = await req.Content.ReadAsAsync<AccountEventDTO>();

    if (accountEvent != null && accountEvent.Name != null)
    {
        // Serialization
        var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(accountEvent));
        var memoryStream = new MemoryStream(bytes, writable: false);
        var message = new BrokeredMessage(memoryStream) { SessionId = Guid.NewGuid().ToString() };

        await accountCreatedTopic.AddAsync(message);
        return req.CreateResponse(HttpStatusCode.OK, "Account successfully added to topic.");
    }

    return req.CreateResponse(HttpStatusCode.BadRequest, "Account was not formed well.");
}
[FunctionName("AccountCreatedSubscriber")]
public static void Run([ServiceBusTrigger("topic-name", "license-keys", Connection = "BusConnectionString")]BrokeredMessage accountEvent, ILogger log)
{
    // ERROR on this line during deserialization
    var account = accountEvent.GetBody<AccountEventDTO>();

    var accountAddedEvent = Mapper.Map<AccountEventDTO, AccountAddedEvent>(account);
    _accountHandler.Handle(accountAddedEvent);
    GenericLogger.AccountLogging(log, accountAddedEvent);
}
public class AccountEventDTO : IAccountEvent
{
    public string Name { get; set; }
    public string SugarId { get; set; }
    public string AccountSubTypeRaw { get; set; }
    public AccountType AccountType { get; set; } = AccountType.Customer;
    public AccountSubType? AccountSubType { get; set; } = null;
    public string Phone { get; set; }
    public string PhoneAlternate { get; set; }
    public string BillingAddressCity { get; set; }
    public string BillingAddressCountry { get; set; }
    public string BillingAddressPostalCode { get; set; }
    public string BillingAddressState { get; set; }
    public string BillingAddressStreet { get; set; }
    public string ShippingAddressCity { get; set; }
    public string ShippingAddressCountry { get; set; }
    public string ShippingAddressPostalCode { get; set; }
    public string ShippingAddressState { get; set; }
    public string ShippingAddressStreet { get; set; }
    public string Website { get; set; }
}
var jsonString = JsonConvert.SerializeObject(accountEvent);
var message = new BrokeredMessage(jsonString);
message.SessionId = Guid.NewGuid().ToString();
message.ContentType = "application/json";
var content = accountEvent.GetBody<string>();
var account = JsonConvert.DeserializeObject<AccountEventDTO>(content);
接收反序列化:

[FunctionName("AccountCreatedHook")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req,
    TraceWriter log, [ServiceBus("topic-name", Connection = "BusConnectionString", EntityType = Microsoft.Azure.WebJobs.ServiceBus.EntityType.Topic)] IAsyncCollector<BrokeredMessage> accountCreatedTopic)
{
    var accountEvent = await req.Content.ReadAsAsync<AccountEventDTO>();

    if (accountEvent != null && accountEvent.Name != null)
    {
        // Serialization
        var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(accountEvent));
        var memoryStream = new MemoryStream(bytes, writable: false);
        var message = new BrokeredMessage(memoryStream) { SessionId = Guid.NewGuid().ToString() };

        await accountCreatedTopic.AddAsync(message);
        return req.CreateResponse(HttpStatusCode.OK, "Account successfully added to topic.");
    }

    return req.CreateResponse(HttpStatusCode.BadRequest, "Account was not formed well.");
}
[FunctionName("AccountCreatedSubscriber")]
public static void Run([ServiceBusTrigger("topic-name", "license-keys", Connection = "BusConnectionString")]BrokeredMessage accountEvent, ILogger log)
{
    // ERROR on this line during deserialization
    var account = accountEvent.GetBody<AccountEventDTO>();

    var accountAddedEvent = Mapper.Map<AccountEventDTO, AccountAddedEvent>(account);
    _accountHandler.Handle(accountAddedEvent);
    GenericLogger.AccountLogging(log, accountAddedEvent);
}
public class AccountEventDTO : IAccountEvent
{
    public string Name { get; set; }
    public string SugarId { get; set; }
    public string AccountSubTypeRaw { get; set; }
    public AccountType AccountType { get; set; } = AccountType.Customer;
    public AccountSubType? AccountSubType { get; set; } = null;
    public string Phone { get; set; }
    public string PhoneAlternate { get; set; }
    public string BillingAddressCity { get; set; }
    public string BillingAddressCountry { get; set; }
    public string BillingAddressPostalCode { get; set; }
    public string BillingAddressState { get; set; }
    public string BillingAddressStreet { get; set; }
    public string ShippingAddressCity { get; set; }
    public string ShippingAddressCountry { get; set; }
    public string ShippingAddressPostalCode { get; set; }
    public string ShippingAddressState { get; set; }
    public string ShippingAddressStreet { get; set; }
    public string Website { get; set; }
}
var jsonString = JsonConvert.SerializeObject(accountEvent);
var message = new BrokeredMessage(jsonString);
message.SessionId = Guid.NewGuid().ToString();
message.ContentType = "application/json";
var content = accountEvent.GetBody<string>();
var account = JsonConvert.DeserializeObject<AccountEventDTO>(content);
var content=accountEvent.GetBody();
var account=JsonConvert.DeserializeObject(内容);

我完全同意,我暂时不得不坚持使用v1有一些原因,但您的回答为我指明了正确的方向。谢谢。设计理由:最新的Microsoft.Azure.ServiceBus中删除了内置POCO序列化支持。这是因为“虽然这种隐藏的序列化魔法很方便,但应用程序应该显式控制对象序列化,并在将其对象图包含到消息之前将其转换为流,并在接收方执行相反的操作。这会产生可互操作的结果。”是否需要设置sessionid?我这样问是因为你可以避免操纵brokeredmessage并直接与你的POCOYes合作。我们的主题依赖FIFO,为了确保这一点,我们必须有一个会话ID。