Search code examples
c#asp.netazuremembership-provider

ASP.NET TableStorageProvider for Azure tables not persisting users?


I have a windows azure Webrole application using Silverlight on top of WCF+ASP.NET. I found this useful ASP.NET provider for Azure tables in the Azure samples and implemented it. I authenticate my users with the WCF service System.Web.ApplicationServices.AuthenticationService.

It works great: I create my users with a very simple ASP.NET form, then I go to my Silverlight app and authenticate successfully, but when I shutdown the Azure development storage environment and restart it, I can't log in again, even if the user is still in the Membership table. I debugged the logging process and found that when the provider executes the query to the table, it throw an exception in this method:

private MembershipRow GetUserFromTable(DataServiceContext svc, string username)
    {
        SecUtility.CheckParameter(ref username, true, true, true, Constants.MaxTableUsernameLength, "username");

        DataServiceQuery<MembershipRow> queryObj = svc.CreateQuery<MembershipRow>(_tableName);

        var query = (from user in queryObj
                     where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) &&
                           user.ProfileIsCreatedByProfileProvider == false
                     select user).AsTableServiceQuery();

        IEnumerable<MembershipRow> allUsers = query.Execute();
        if (allUsers == null)
        {
            return null;
        }
        IEnumerator<MembershipRow> e = allUsers.GetEnumerator();
        if (e == null)
        {
            return null;
        }
        // e.Reset() throws a not implemented exception
        // according to the spec, the enumerator is at the beginning of the collections after a call to GetEnumerator()
        if (!e.MoveNext())
        {
            return null;
        }
        MembershipRow ret = e.Current;
        if (e.MoveNext())
        {
            throw new ProviderException("Duplicate elements for primary keys application and user name.");
        }
        return ret;
    }

the queryObj variable contains the user entry when I check during execution, but query looks like it contains an exception in one of its member. Finally, the execution fails when making the e.moveNext().

If I just delete all the Membership tables and blobs and recreate a user, it works just normally.


Solution

  • The samples from the sdk are not production ready. There are newer versions in the Windows Azure Toolkit for Windows Phone 7 and in the Windows Azure Training Kit. You might have problems in the dev environment if you don't shut down your browser between different user sessions because of the session management in blob storage not getting cleared. We have used them in our book and tested with no problem.