La comunicazione tra Javascript and Silverlight è una tecnica che spesso rende molto semplice e potente l’introduzione di miglioramenti grafici nonché funzionali in applicazioni web preesistenti. In questo post viene mostrato nello specifico come integrare un password checker realizzato in Silverlight all’interno di un form ASP.NET di partenza, sfruttando javascript come “collante”.
Supponiamo by design che il password checker stabilisca 6 livelli di complessità raggruppabili in tre categorie: “Weak”,”Normal” e “Strong”:
1. Page.xaml
Partiamo dalla definizione del password checker in Silverlight. Gli elementi della UI di tale controllo, come mostrato nella figura sopra riportata, sono costituiti da 6 Rectangle ed un TextBlock disposti orizzontalmente all’interno di uno StackPanel.
<UserControl x:Class="SilverlightAppPasswordStrength.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
...
<Grid x:Name="LayoutRoot">
<StackPanel x:Name="mainPanel" Orientation="Horizontal">
<Rectangle ...></Rectangle>
<Rectangle ... Margin="2,0,0,0"></Rectangle>
<Rectangle ... Margin="2,0,0,0"></Rectangle>
<Rectangle ... Margin="2,0,0,0"></Rectangle>
<Rectangle ... Margin="2,0,0,0"></Rectangle>
<Rectangle ... Margin="2,0,0,0"></Rectangle>
<TextBlock x:Name="txtPwdStrength" ... Margin="5,2,0,0"></TextBlock>
</StackPanel>
</Grid>
</UserControl>
2. Page.xaml.cs
Nell’implementazione, il comportamento della UI è in mano ad un metodo NotifyStrengthLevel che sostanzialmente si prende carico di gestire il layout degli elementi in base al livello di complessità (da 0 a 5) restituito da un metodo GetPasswordStrengthLevel che implementa l’algoritmo di password cecking. Due note:
- Tramite il metodo HtmlPage.RegisterScriptableObject possiamo “registrare” il nostro oggetto Page di Silverlight all’interno di una pagina (X)Html in modo da abilitare l’accesso da parte di javascript
- Per essere invocabile via javascript, il metodo NotifyStrengthLevel dell’oggetto Page deve essere decorato con l’attributo ScriptableMember.
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
HtmlPage.RegisterScriptableObject("PwdStrengthControl", this);
}
[ScriptableMember]
public void NotifyStrengthLevel(string pwd)
{
SolidColorBrush color = null;
string text = null;
int level = GetPasswordStrengthLevel(pwd);
if (level <= 1)
{
color = new SolidColorBrush(Colors.Red);
text = "Weak";
}
else if (level > 1 && level <= 3)
{
color = new SolidColorBrush(Colors.Orange);
text = "Normal";
}
else if (level > 3 && level <= 5)
{
color = new SolidColorBrush(Colors.Green);
text = "Strong";
}
else throw new ArgumentException(string.Format("Invalid Strength level: {0}",level));
txtPwdStrength.Text = text;
txtPwdStrength.Foreground = color;
IEnumerable<Rectangle> rects = mainPanel.Children.OfType<Rectangle>();
foreach (Rectangle rect in rects) rect.Fill = new SolidColorBrush(Colors.LightGray);
for (int i = 0; i <= level; i++) rects.ElementAt(i).Fill = color;
}
private int GetPasswordStrengthLevel(string pwd)
{
int level = 0;
// Algoritmo per determinare il livello di sicurezza della password
return level;
}
}
3. Test.aspx
A questo punto, il nostro password checker in Silverlight è pronto per essere acceduto via javascript analizzando il DOM del form ASP.NET host. Nel seguente codice viene mostrata una possibile implementazione: ogni volta che si scatena l’evento client-side onkeyup sulla TextBox per l’inserimento della password, viene invocata una funzione javascript CheckPwdStrength che si occupa di gestire l’interazione con l’oggetto Silverlight. Da notare in particolare la sintassi:
document.getElementById("<silverlightControl>").Content.<ScriptableObject>.<ScriptableMember>(...);
utilizzata per invocare il metodo di interesse NotifyStrengthLevel (ScriptableMember) definito all’interno dell’oggetto Silverlight registrato.
<script type="text/javascript">
function CheckPwdStrength(pwd)
{
var control = document.getElementById("xamlPwdStrength");
if (pwd.length == 0) control.style.visibility = 'hidden';
else
{
control.style.visibility = 'visible';
control.Content.PwdStrengthControl.NotifyStrengthLevel(pwd);
}
}
</script>
. . .
<asp:TextBox ID="txtPassword" runat="server" TextMode="Password" onkeyup="CheckPwdStrength(this.value)" />
<asp:Silverlight ID="xamlPwdStrength" runat="server" Source="~/ClientBin/SilverlightAppPasswordStrength.xap" MinimumVersion="2.0.31005.0" Height="15px" />
. . .