PasswordCredential BackgroundTransfer

岁酱吖の 提交于 2019-12-08 10:03:40

问题


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?


回答1:


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




回答2:


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().



来源:https://stackoverflow.com/questions/27178552/passwordcredential-backgroundtransfer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!