I've been searching the web for this, and couldn't really find a solution that actually worked. Situation is as follows: I've got a WPF application, where I want to present the user with a simple logon form. Trying to work MVVM, so I've got a LoginViewModel with the following code behind the login command:
try
{
WithClient(servfact.GetServiceClient<IAccountService>(), proxy =>
{
principal = proxy.AuthenticateUser(Login, password);
});
Thread.CurrentPrincipal = principal;
}
catch(...) { ... }
"WithClient" is a short method in my viewmodel baseclass, which I use to instantiate and dispose of my service proxies:
protected void WithClient<T>(T proxy, Action<T> codeToExecute)
{
try { codeToExecute(proxy); }
finally
{
IDisposable toDispose = (proxy as IDisposable);
if(toDispose != null) { toDispose.Dispose(); }
}
}
Now, most of my services are Async, and I've got an async variant of WithClient going on, which also works fine:
protected async Task WithClientAsync<T>(T proxy, Func<T, Task> codeToExecute)
{
try { await codeToExecute(proxy); }
finally
{
IDisposable toDispose = (proxy as IDisposable);
if(toDispose != null) { toDispose.Dispose(); }
}
}
The trouble begins whenever I also want to do the login asynchronously. Obviously I don't want the UI to freeze up as I do the login (or visit any WCF service for that matter). That in itself is working fine, but the problem sits in the piece of code where I set the CurrentPrincipal. This problem is probably familiar to most of you: it seems to set it just fine. Then in my program I want to use the CurrentPrincipal (either on the client side or to send the users login to a WCF service in a messageheader), but it seems to be reset to a standard GenericPrincipal. When I revert the login back to being synchronous, the CurrentPrincipal is just fine. So in short: how do I set the principal in the asynchronous code, having it persist later on, instead of reverting back to a standard principal?
Well, well, no answer in a year. No worries, since I managed to solve this myself: I simply wrapped a singleton around it all:
public sealed class CurrentPrincipalFacade : IPrincipal
{
#region Singleton mechanism
private static readonly CurrentPrincipalFacade instance = new CurrentPrincipalFacade();
public static CurrentPrincipalFacade Instance { get { return instance; } }
private CurrentPrincipalFacade() { }
#endregion
#region IPrincipal members
public IPrincipal Principal { get; set; }
public IIdentity Identity { get { return Principal == null ? null : Principal.Identity; } }
public bool IsInRole(string role) { return Principal != null && Principal.IsInRole(role); }
public void Reset() { Principal = new GenericPrincipal(new GenericIdentity(""), new string[] { }); }
#endregion}
So I set that after login. I guess the problem was I was setting the principal in another thread, which got lost when I got out of that?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.