Caliburn Micro Login Dialog

May 3, 2011 at 12:48 AM

I am trying to add a Login dialog to my Caliburn micro application.

It looks like the most appropriate place to open this dialog is to override the "DisplayRootView" of the bootstrapper.

However, I am noticing that the calls to "TryClose()" in my LoginViewModel, not only close the LoginDialog as expected, but also the ShellView that gets displayed after the LoginView is shown.

I have managed to reproduce this behaviour in the "HelloWindowManager" sample.

I was wondering if anyone else has experienced this, and what the most appropriated method of displaying a Login Dialog is.

TIA

Liam

May 3, 2011 at 10:22 AM

I would leave the shell as the root visual and then use the ShellView as an area you can load content into. something like this

 

<Window x:Class="Caliburn.Micro.HelloWindowManager.ShellView"      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="640"
        Height="480">
    <ContentControl x:Name="ActiveItem"/>
</Window>

 

Your login view can then be a UserControl instead of a Window and Caliburn will bind to the active view in the ViewModel.

 

    public class ShellViewModel : Conductor<IScreen>
    {
        public ShellViewModel()
        {
            ActivateItem(new LoginViewModel());
        }
    }

 

You can also used Conductors to manage the life cylce of your views. The above example is setting the ActiveItem property of the base Conductor. Because the Name is the same it will mind the LoginViewModel with the LoginView and inject it into the ActiveItem content control.  The conductor manages your screens for you and gives them a proper life cycle of Activating, Deactivating, Closing, CanClose. so for you login viewmodel it could look like this

 

    public class LoginViewModel : Screen
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        
        public void Login( )
        {
            //Login logic
        }
    }

 

 

Because your shell manages a Screen you can load any viewmodel that inherits Screen or implements IScreen. In this example your LoginView might look like this

 

<UserControl x:Class="Sample.Views.LoginView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">

    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <TextBlock Text="Username:"/>
            <TextBox x:Name="Username"/>
        </StackPanel>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <TextBlock Text="Password:"/>
            <TextBox x:Name="Password"/>
        </StackPanel>
        <Button Grid.Row="2" x:Name="Login"/>
    </Grid>
</UserControl>

You might be wondering how you know when to change the active screen in the Shell View. This can be done via the Event Aggregator where your shell can subscribe to a message and your login viewmodel can publish the message. This blog post has a good implementation of this, http://sonyarouje.wordpress.com/2010/11/07/an-introduction-to-caliburn-micro/

May 5, 2011 at 3:19 AM

Thanks for you help Nitro,

We ended up having to wait for the Shell view to be displayed before calling the WindowManager.Showdialog(). Although not desirable, this will work for now.

Coordinator
May 5, 2011 at 11:56 AM

The problem is the shutdown mode you are running under http://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode.aspx OnExplicitShutdown, then call Shutdown after your shell closes.

May 6, 2011 at 1:42 AM

Thanks Rob, it seems obvious now that you point it out. Worked like a charm

Sep 21, 2011 at 6:23 AM
Edited Sep 21, 2011 at 6:24 AM

I'm currently integrating a login dialog and I'm asking myself calling the login dialog from the bootstrapper or from the shell. Are there any security issues to consider? What is the securer approach, shell/bootstrapper?

Sep 23, 2011 at 12:19 PM

No security specialists here?

Sep 23, 2011 at 8:18 PM

I'm not aware of particular security issues regarding the *place* where the password is asked (but I'm not a security expert).
Do you have a potential security threat in mind?

Sep 25, 2011 at 10:29 AM
Edited Sep 26, 2011 at 9:07 AM

I don't have a particular security threat in mind, but I think if the login is called after the shell is loaded, this may opens a door for attacks. If the login dialog is called from the bootstrapper, nothing is loaded in case the login fails. With other words, the first approach makes more available for unauthorized users. I don't know, maybe this thoughts are baseless.

Sep 26, 2011 at 7:46 PM

I found this pretty good article about it: http://msdn.microsoft.com/en-us/magazine/ff646975.aspx

It seems that excessive efforts to protect the login dialog (within the SL app flow) would be useless, since a malicious user could decompile xap and understand the logic behind it.
Obfuscation just mitigate this risk.
The most effective method seems to be securing services, integrating the SL login with the ASP.NET pipeline: http://msdn.microsoft.com/en-us/library/dd560704(VS.96).aspx
This also allows to split the app in two parts: a login one, deployed in a public area of the site and the actual app, contained in a xap within a restricted are of the site, accessible to authenticated users only.

Sep 27, 2011 at 4:22 PM

Thanks a lot for your information.