3
votes

I have seen similar questions to this answered that are using SQL Server and Nhibernate persistence. But hows about with Azure Storage?

I have a class that holds Saga data. That contains a property that is a collection:

public class ResetPolicyData : ContainSagaData
{
    public int NumberOfEmailsInGroup { get; set; }
    public Guid EmailGroupId { get; set; }

    public List<PasswordResetInformation> PasswordResetInformation { get; set; }
}

PasswordResetInformation contains a couple of simple string properties and thats it.

When the saga attempts to persist the data to Azure Storage I get the following error:

The property type 'List 1' is not supported in windows azure table storage at NServiceBus.Persistence.AzureStorage.AzureSagaPersister.ToDictionaryTableEntity(Object entity, DictionaryTableEntity toPersist, IEnumerable`1 properties) in C:\Build\src\NServiceBus.Persistence.AzureStorage\SagaPersisters\AzureSagaPersister.cs:line

In my EndpointConfig I have the following so I guess I was sort of expecting NServiceBus to magically serialize PasswordResetInformation into JSON and just store it:

endpointConfiguration.UseSerialization<JsonSerializer>();

So my question: Is there a way to persist a List or other collection in Saga Data to AzureStorage?

2

2 Answers

4
votes

Azure storage only supports primitive types. Therefore, anything else should be serialized (JSON, like you've suggested would work) and stored as a simple type as well. This should be documented and here's a link to track that documentation progress.

0
votes

Here is my work around/hack to make this work:

public class ResetPolicyData : ContainSagaData
{
    public int NumberOfEmailsInGroup { get; set; }
    public string Email { get; set; }

    /// <summary>
    /// Dont reference directly. Only here for persisting data to Azurestorage. Use
    /// AddPasswordResetInformation/GetPasswordResetInformation instead.
    /// </summary>
    public string PasswordResetInformationJson { get; set; }

    #region Handle Searilize and Desearilize PasswordResetInformation 

    public void AddPasswordResetInformation(PasswordResetInformation value)
    {
        if (value == null) return;

        //Hydrate collection
        var collection = string.IsNullOrEmpty(PasswordResetInformationJson) ? 
            new List<PasswordResetInformation>() : JsonConvert.DeserializeObject<List<PasswordResetInformation>>(PasswordResetInformationJson);

        //Check is unique before adding
        if(!collection.Contains(value)) collection.Add(value);

        PasswordResetInformationJson = JsonConvert.SerializeObject(collection);
    }

    public List<PasswordResetInformation> GetPasswordResetInformation()
    {
        return string.IsNullOrEmpty(PasswordResetInformationJson) ? 
            new List<PasswordResetInformation>() : JsonConvert.DeserializeObject<List<PasswordResetInformation>>(PasswordResetInformationJson);
    }

    #endregion
}