Deserialize strongly typed object from Azure Servi

2019-08-05 06:16发布

for whatever reason I can't seem to figure out how to pull my object out of my queue and deserialize it back into what it was placed into it as (An AccountEventDTO).

Azure function successfully placing object into queue:

[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.");
}

Azure function pulling object from queue:

[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);
}

Error message:

Deserialization Error

AccountEventDTO:

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; }
}

2条回答
疯言疯语
2楼-- · 2019-08-05 06:28

You're using BrokeredMessage (old Azure Service Bus client for .NET, WindowsAzure.ServiceBus). When message is sent as memory stream, it has to be received and deserialized using the same approach. GetBody<T> will work if you construct BrokeredMessage passing in an object of type T.

Note: the next generation client (Microsoft.Azure.ServiceBus) only works raw with byte array (memory stream for the old client). If this is a new project, recommend to stick with that approach rather than serialized types. More info is available in a GitHub issue here.

查看更多
对你真心纯属浪费
3楼-- · 2019-08-05 06:47

Ended up solving this by altering the way I was serializing my message on the send side and how I was pulling it down on the receiving side.

Sending Serialization:

var jsonString = JsonConvert.SerializeObject(accountEvent);
var message = new BrokeredMessage(jsonString);
message.SessionId = Guid.NewGuid().ToString();
message.ContentType = "application/json";

Receiving Deserialization:

var content = accountEvent.GetBody<string>();
var account = JsonConvert.DeserializeObject<AccountEventDTO>(content);
查看更多
登录 后发表回答