我需要验证两个密码字段。如果它们匹配,则必须在验证视图模型中验证凭证。我在验证视图模型中设置了bool值validPassword,需要在视图中引用它。然后根据validPassword值在视图中执行某些操作。但是,当我在视图中引用validPassword时,validPassword始终为false,即使在viewmodel中为true也是如此。
视图模型:
internal static bool validPassword;
public static bool CheckCredentials(string username, string password, string domain)
{
string userPrincipalName = username + "@" + domain + ".com";
try
{
using(var context = new PrincipalContext(ContextType.Domain, domain))
{
validPassword = true;
return context.ValidateCredentials(userPrincipalName, password);
}
}
catch // a bogus domain causes an LDAP error
{
errorsForPassword.Add("Invalid Login!");
validPassword = false;
return false;
}
}
视图背后的代码:
private void PwBox_OnKeyDown(object sender, RoutedEventArgs e)
{
System.Windows.Controls.ToolTip toolTip = new System.Windows.Controls.ToolTip();
//PasswordBox passwordBox = sender as PasswordBox;
passwordAgain = PasswordAgainBox.Password;
if(string.IsNullOrEmpty(passwordAgain) || !string.Equals(passwordAgain, MiscParameterViewModel.password))
{
PwBoxBorder.BorderBrush = new SolidColorBrush(Colors.Red);
MiscParameterViewModel.nextButtonIsEnabled = false;
if(string.IsNullOrEmpty(passwordAgain))
{
toolTip.Content = "Please enter the password again!";
ToolTipService.SetToolTip(PasswordAgainBox, toolTip);
}
else if(!string.Equals(passwordAgain, MiscParameterViewModel.password))
{
toolTip.Content = "Passwords don't match!";
ToolTipService.SetToolTip(PasswordAgainBox, toolTip);
}
}
else
{
//ToolTipService.SetToolTip(PasswordAgainBox, null);
//PwBoxBorder.BorderBrush = new SolidColorBrush(Colors.Transparent);
_validationViewModel.Authenticate();
if(!ValidationViewModel.validPassword)
{
toolTip.Content = "Invalid password!";
ToolTipService.SetToolTip(PasswordBox, toolTip);
ToolTipService.SetToolTip(PasswordAgainBox, toolTip);
PwBoxBorder.BorderBrush = new SolidColorBrush(Colors.Red);
PwBoxAgainBorder.BorderBrush = new SolidColorBrush(Colors.Red);
}
else
{
ToolTipService.SetToolTip(PasswordBox, null);
ToolTipService.SetToolTip(PasswordAgainBox, null);
PwBoxBorder.BorderBrush = new SolidColorBrush(Colors.Transparent);
PwBoxAgainBorder.BorderBrush = new SolidColorBrush(Colors.Transparent);
}
}
}
Authenticate是viewmodel中的异步方法,它调用CheckCredentials方法。
以下是Authenticate方法:
public async void Authenticate()
{
MiscParameterViewModel.nextButtonIsEnabled = false;
NotifyPropertyChanged("NextButtonIsEnabled");
const string propertyKey = "Password";
bool isValid = false;
/* Call service asynchronously */
if(MiscParameterViewModel.servServiceLoginType == ServiceLoginTypes.Windows)
{
if(errorKeys.ContainsKey(propertyKey))
{
errorsForPassword.Clear();
errorKeys.TryRemove(propertyKey, out errorsForPassword);
/* Raise event to tell WPF to execute the GetErrors method */
RaiseErrorsChanged(propertyKey);
}
//if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(passwordAgain))
if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
errorsForPassword.Add("Login is required!");
errorKeys.TryAdd(propertyKey, errorsForPassword);
isValid = false;
}
else
{
isValid = await Task<bool>.Run(() =>
{
return CheckCredentials(username, password, domain);
})
.ConfigureAwait(false);
}
}
答案 0 :(得分:1)
发生的事情是您的Authenticate方法正在另一个线程上执行CheckCredentials,然后将控制权返回给您的视图。这意味着你(有时)会走到这一行:
if(!ValidationViewModel.validPassword)
在调用CheckCredentials之前。您看到了错误,因为它是布尔值的默认值 - 它尚未设置。
您可以通过几种不同的方式解决此问题。您可以从authenticate方法返回一个Task,然后在检查validPassword之前调用该任务上的.Wait()。
或者你可以简单地从Authenticate方法中删除async / await并使其成为同步方法。哪个是正确的取决于你的应用程序的其余部分。
编辑:这是我对您的身份验证方法的尝试。我不得不猜测你想要的一些功能。
public async Task<bool> Authenticate()
{
MiscParameterViewModel.nextButtonIsEnabled = false;
NotifyPropertyChanged("NextButtonIsEnabled");
const string propertyKey = "Password";
/* Call service asynchronously */
if(MiscParameterViewModel.servServiceLoginType == ServiceLoginTypes.Windows)
{
if(errorKeys.ContainsKey(propertyKey))
{
errorsForPassword.Clear();
errorKeys.TryRemove(propertyKey, out errorsForPassword);
/* Raise event to tell WPF to execute the GetErrors method */
RaiseErrorsChanged(propertyKey);
}
//if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(passwordAgain))
if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
errorsForPassword.Add("Login is required!");
errorKeys.TryAdd(propertyKey, errorsForPassword);
return false;
}
else
{
return await Task<bool>.Factory.StartNew(() => CheckCredentials(username, password, domain));
}
}
return false;
}
一旦你完成任务,你就必须决定如何处理它。如果你只是打电话给.Wait(),它会起作用,但是当你等待时,你会遇到GUI冻结的问题。
您可能希望使用.ContinueWith()方法,该方法将在任务完成后调用,然后在那里您可以更新密码框。您可能需要将更改编组回GUI线程(ContinueWith将在另一个线程上)来设置密码框的值 - 如果没有完整的解决方案,则不确定。希望有所帮助