public async Task <IHttpActionResult> Login([FromBody] AccountLoginInfo info)
        {
            Logger.Info($"Account.Login AccountName={info.AccountName}");

            var accountResourceByName =
                await
                this.DatabaseContext.Bucket.GetByEntityIdSlimAsync <AccountResourceEntity>(
                    AccountResourceEntity.GenerateResourceId(AccountResourceType.AccountName, info.AccountName),
                    false);

            AccountEntity account = null;

            if (accountResourceByName != null)
            {
                // this means the temp value still exists, we can directly get the account by account id.
                account =
                    await
                    this.DatabaseContext.Bucket.GetByEntityIdSlimAsync <AccountEntity>(
                        accountResourceByName.AccountId);
            }
            else
            {
                // this means the temp value not exists any more, meanwhile, it have passed a period after the account created
                // so the index should be already created and we can query the entity by query string
                account =
                    await
                    this.DatabaseContext.Bucket.FirstOrDefaultAsync <AccountEntity>(
                        a => a.AccountName == info.AccountName);
            }

            if (account == null)
            {
                throw new UCenterException(UCenterErrorCode.AccountNotExist);
            }
            if (!EncryptHashManager.VerifyHash(info.Password, account.Password))
            {
                await
                this.RecordLogin(account, UCenterErrorCode.AccountLoginFailedPasswordNotMatch,
                                 "The account name and password do not match");

                throw new UCenterException(UCenterErrorCode.AccountLoginFailedPasswordNotMatch);
            }
            account.LastLoginDateTime = DateTime.UtcNow;
            account.Token             = EncryptHashManager.GenerateToken();
            await this.DatabaseContext.Bucket.UpsertSlimAsync(account);

            await this.RecordLogin(account, UCenterErrorCode.Success);

            return(CreateSuccessResult(ToResponse <AccountLoginResponse>(account)));
        }
        public async Task <IHttpActionResult> Register([FromBody] AccountRegisterRequestInfo info,
                                                       CancellationToken token)
        {
            this.Logger.Info($"Account.Register AccountName={info.AccountName}");

            var removeTempsIfError = new List <AccountResourceEntity>();
            var error = false;

            try
            {
                var account =
                    await
                    DatabaseContext.Bucket.FirstOrDefaultAsync <AccountEntity>(
                        a => a.AccountName == info.AccountName, false);

                if (account != null)
                {
                    throw new UCenterException(UCenterErrorCode.AccountRegisterFailedAlreadyExist);
                }

                account = new AccountEntity
                {
                    AccountName     = info.AccountName,
                    IsGuest         = false,
                    Name            = info.Name,
                    IdentityNum     = info.IdentityNum,
                    Password        = EncryptHashManager.ComputeHash(info.Password),
                    SuperPassword   = EncryptHashManager.ComputeHash(info.SuperPassword),
                    PhoneNum        = info.PhoneNum,
                    Sex             = info.Sex,
                    CreatedDateTime = DateTime.UtcNow
                };

                if (!string.IsNullOrEmpty(account.AccountName))
                {
                    var namePointer = new AccountResourceEntity(account, AccountResourceType.AccountName);
                    await this.DatabaseContext.Bucket.InsertSlimAsync(namePointer);

                    removeTempsIfError.Add(namePointer);
                }
                if (!string.IsNullOrEmpty(account.PhoneNum))
                {
                    var phonePointer = new AccountResourceEntity(account, AccountResourceType.Phone);
                    await this.DatabaseContext.Bucket.InsertSlimAsync(phonePointer);

                    removeTempsIfError.Add(phonePointer);
                }
                else if (!string.IsNullOrEmpty(account.Email))
                {
                    var emailPointer = new AccountResourceEntity(account, AccountResourceType.Email);
                    await this.DatabaseContext.Bucket.InsertSlimAsync(emailPointer);

                    removeTempsIfError.Add(emailPointer);
                }

                // set the default profiles
                account.ProfileImage = await this.storageContext.CopyBlobAsync(
                    account.Sex == Sex.Female
                    ?this.settings.DefaultProfileImageForFemaleBlobName
                    : this.settings.DefaultProfileImageForMaleBlobName,
                    this.settings.ProfileImageForBlobNameTemplate.FormatInvariant(account.Id),
                    token);

                account.ProfileThumbnail = await this.storageContext.CopyBlobAsync(
                    account.Sex == Sex.Female
                    ?this.settings.DefaultProfileThumbnailForFemaleBlobName
                    : this.settings.DefaultProfileThumbnailForMaleBlobName,
                    this.settings.ProfileThumbnailForBlobNameTemplate.FormatInvariant(account.Id),
                    token);

                await this.DatabaseContext.Bucket.InsertSlimAsync(account);

                return(CreateSuccessResult(ToResponse <AccountRegisterResponse>(account)));
            }
            catch (Exception ex)
            {
                this.Logger.Info($"Account.Register Exception:AccoundName={info.AccountName}");
                this.Logger.Info(ex.ToString());

                error = true;
                if (ex is CouchBaseException)
                {
                    var status = (ex as CouchBaseException).Result as IDocumentResult <AccountResourceEntity>;
                    if (status != null)
                    {
                        throw new UCenterException(UCenterErrorCode.AccountRegisterFailedAlreadyExist, ex);
                    }
                }

                throw;
            }
            finally
            {
                if (error)
                {
                    foreach (var item in removeTempsIfError)
                    {
                        this.DatabaseContext.Bucket.Remove(item.ToDocument());
                    }
                }
            }
        }