我目前正在尝试将手机示例应用从官方广告github repo转换为caliburn.micro MVVM应用。但是有很多移动部件支持代码隐藏以与WebAuthenticationBroker相处,我现在不知道如何在经纪人完成标志后再次激活应用程序时将其推送到视图模型并正确处理导航-上。由于我现在完全无能为力,因此尚无法分享代码。
答案 0 :(得分:0)
我在Windows Phone 8.1 App中一直使用MvvmLight和ADAL。您需要做的是,一旦获得令牌,您需要使用Messenger模式发送消息。所有那些需要令牌并且已经订阅它的视图模型都会收到它。以下是我使用MvvmLight在我的应用中完成的操作。请记住,您需要有一个ContinuationManager类和IWebContinuable接口才能使应用程序正常工作。
private async void Login()
{
AuthenticationResult result = null;
context = AuthenticationContext.CreateAsync("https://login.windows.net/<tenant-id>").GetResults();
try
{
//try to check if you can get the token without showing pop-up
result = await context.AcquireTokenSilentAsync("https://management.core.windows.net/", "<clientid>");
if(result.Status==AuthenticationStatus.ClientError)
{
bool exists = CheckInVault();
if(exists)
{
PasswordVault vault = new PasswordVault();
var tokenvault = vault.FindAllByResource("Token");
string RefreshToken = tokenvault[0].Password;
var refresh=await context.AcquireTokenByRefreshTokenAsync(RefreshToken, clientid);
vault.Remove(tokenvault[0]);
StoreToken(refresh);
}
else
{
context.AcquireTokenAndContinue("https://management.core.windows.net/", clientid, WebAuthenticationBroker.GetCurrentApplicationCallbackUri(), StoreToken);
}
}
else if(result != null && result.Status == AuthenticationStatus.Success)
{
// A token was successfully retrieved. Post the new To Do item
bool exists = CheckInVault();
if (exists)
{
PasswordVault vault = new PasswordVault();
var tokenvault = vault.FindAllByResource("Token");
vault.Remove(tokenvault[0]);
}
StoreToken(result);
}
//this method will be called when app is opened first time and pop-up appears
result=await context.AcquireTokenSilentAsync("https://management.core.windows.net/", "<client-id>");
}
catch(Exception e)
{
MessageDialog dialog = new MessageDialog("Error");
}
}
我在这里做的是 - 在用户首先注册时获取访问令牌和引用令牌后,我将刷新令牌存储在PasswordVault中,以便将来启用它以启用单点登录。 ADAL确实使用了其缓存功能,但有时单点登录失败,因此使用PasswordVault存储刷新令牌。身份验证完成后,我有一个StoreToken函数的委托,我实际存储了新的刷新令牌,并使用MvvmLight中的Messenger类将访问令牌发送给所有订阅者。
private void StoreToken(AuthenticationResult result)
{
try
{
var token = result.AccessToken;
Messenger.Default.Send<string>(token); //send the access token.
PasswordVault vault = new PasswordVault();
PasswordCredential credential = new PasswordCredential();
credential.UserName = result.AccessToken;
credential.Password = result.RefreshToken;
credential.Resource = "Token";
vault.Add(credential);
}
catch(Exception e)
{
}
}
我建议在视图模型中处理导航。定义一个辅助类,如NavigationService:
public class NavigationService:INavigationService
{
private Frame _frame;
public Frame Frame
{
get
{
return _frame;
}
set
{
_frame = value;
_frame.Navigated+= OnFrameNavigated;
}
}
public void NavigateTo(string type)
{
Frame.Navigate(Type.GetType(type));
}
public void GoForward()
{
if (Frame.CanGoForward)
Frame.GoForward();
}
public void GoBack()
{
if (Frame.CanGoBack)
Frame.GoBack();
}
}
要从视图模型导航到页面,请使用NavigateTo(string)方法
NavigateTo("<fully qualified class name of the page you want to navigate to>,<assembly name>")
我还建议使用IoC容器(MvvmLight为您提供ViewModelLocator类),以便您可以维护视图模型的单例实例和NavigationService等帮助程序。我还没有使用过CaliburnMicro框架,但我认为Messaging和Dependency Injection会有类似的功能。