PasswordCredential BackgroundTransfer

0

Im creating a new BackgroundTransfer and adding Server Credentials:

PasswordCredential webdavLogin = new PasswordCredential();
webdavLogin.UserName = ServerSettings.Values["serverUsername"].ToString();
webdavLogin.Password = ServerSettings.Values["serverPassword"].ToString();
uploader.ServerCredential = webdavLogin;

Now the problem is, everytime i run the BackgroundTransfer, the following exception raises:

Exception from HRESULT: 0x80070565
The maximum number of secrets that may be stored in a single system has been exceeded

I searched the CredentialStore, but it is empty, there are no Credentials stored. What can i do?

c#
.net
windows-phone-8.1
credentials
asked on Stack Overflow Nov 27, 2014 by andy12

2 Answers

0

I ran into exactly the same problem. The BackgroundTransfer is obviously adding them into the PasswordVault itself. You could try not creating a new instance of PasswordCredential but ensuring it is in the PasswordVault (adding if it is not there) and retrieving it. This might stop the BackgroundTransfer adding it in multiple times. You still need to watch the maximum number of credentials that can be stored on the phone... some weird number like 161 comes to mind, but I'm not sure.

Alternatively, what I did as I only required basic authentication, was to create the request header with the authentication details myself (an instance of BackgroundUploader has a method SetRequestHeader that you can use).

    var uploader = new BackgroundUploader
    {
        //ServerCredential = new PasswordCredential {UserName = uploadUser.Name, Password= uploadUser.Password}
    };
    var authHeader = Headers.GetAuthorizationHeader(uploadUser.Name, uploadUser.Password);
    uploader.SetRequestHeader(authHeader.Key,authHeader.Value);

    KeyValuePair<string, string> GetAuthorizationHeader(string username, string password)
    {
        return new KeyValuePair<string, string>(Authorization, "Basic " + EncodeToBase64(string.Format("{0}:{1}", username, password)));
    }

    string EncodeToBase64(string toEncode)
    {
        var bytes = Encoding.UTF8.GetBytes(toEncode);
        var returnValue = Convert.ToBase64String(bytes);
        return returnValue;
    }

Given my scenario, this was easier than managing credentials through the PasswordVault

answered on Stack Overflow Nov 28, 2014 by Michael Smith
0

You can have only 20 outstanding operations with credentials.

If you believed there are no operations running at the time, chances are there are 10 forgotten or broken operations in the cache. AttachAsync() all of them and cancel them immediately.

Here is an example:

private async Task CancelAll()
{
    // Get all running operations.
    var downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
    Debug.WriteLine(downloads.Count);

    var cancellationTokenSource = new CancellationTokenSource();
    List<Task> tasks = new List<Task>();
    foreach (var download in downloads)
    {
        var task = download.AttachAsync().AsTask(cancellationTokenSource.Token);
        tasks.Add(task);
    }

    try
    {
        // Cancel all the operations. It is expected they will throw exception.
        cancellationTokenSource.Cancel();
        Task.WaitAll(tasks.ToArray());
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex);
    }

    Debug.WriteLine("All canceled!");
}

Then, schedule the new operations with DownloadOperation.StartAsyn().

answered on Stack Overflow Dec 14, 2014 by kiewic

User contributions licensed under CC BY-SA 3.0