string
is an alias in C# for System.String
.
So technically, there is no difference. It's like int
vs. System.Int32
.
As far as guidelines, it's generally recommended to use string
any time you're referring to an object.
e.g.
string place = "world";
Likewise, I think it's generally recommended to use String
if you need to refer specifically to the class.
e.g.
string greet = String.Format("Hello {0}!", place);
This is the style that Microsoft tends to use in their examples.
It appears that the guidance in this area may have changed, as StyleCop now enforces the use of the C# specific aliases.
Maybe I am missing something, but it seems like most of these solutions overcomplicate things and do away with secure practices.
This method does not violate the MVVM pattern and maintains complete security. Yes, technically it is code behind, but it is nothing more than a "special case" binding. The ViewModel still has no knowledge of the View implementation, which in my mind it does if you are trying to pass the PasswordBox in to the ViewModel.
Code Behind != Automatic MVVM violation. It all depends on what you do with it. In this case, we are just manually coding a binding, so its all considered part of the UI implementation and therefore is ok.
In the ViewModel, just a simple property. I made it "write only" since there shouldn't be a need to retrieve it from outside the ViewModel for any reason, but it doesn't have to be. Note that it is a SecureString, not just a string.
public SecureString SecurePassword { private get; set; }
In the xaml, you set up a PasswordChanged event handler.
<PasswordBox PasswordChanged="PasswordBox_PasswordChanged"/>
In the code behind:
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
if (this.DataContext != null)
{ ((dynamic)this.DataContext).SecurePassword = ((PasswordBox)sender).SecurePassword; }
}
With this method, your password remains in a SecureString at all times and therefore provides maximum security. If you really don't care about security or you need the clear text password for a downstream method that requires it (note: most .NET methods that require a password also support a SecureString option, so you may not really need a clear text password even if you think you do), you can just use the Password property instead. Like this:
(ViewModel property)
public string Password { private get; set; }
(Code behind)
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
if (this.DataContext != null)
{ ((dynamic)this.DataContext).Password = ((PasswordBox)sender).Password; }
}
If you wanted to keep things strongly typed, you could substitute the (dynamic) cast with the interface of your ViewModel. But really, "normal" data bindings aren't strongly typed either, so its not that big a deal.
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
if (this.DataContext != null)
{ ((IMyViewModel)this.DataContext).Password = ((PasswordBox)sender).Password; }
}
So best of all worlds - your password is secure, your ViewModel just has a property like any other property, and your View is self contained with no external references required.
Best Answer
Personally I just pass the entire
PasswordBox
control to my LoginCommandI know it breaks MVVM because the ViewModel layer now references a View-specific object, but I think in this specific case it's OK.
So I might have XAML that looks like this:
And a
LoginCommand
that does something like this:I suppose you could also run some kind of encryption algorithm on the value and compare the hash of that value to the hash of the user's password too
I'm no expert on the
PasswordBox
control or security, but I do know that you don't want to be storing the user's password in plain text anywhere in memory within your application(Technically, it's stored as plain text in
PasswordBox.Password
- you can use something like Snoop to verify this if you want - however typically the PasswordBox doesn't exist for longer than it takes the user to login, and the actual "password" is just text entered by the user, which may or may not be correct. A keylogger could get you the same information.)