Silverlight的数据验证Input validation

本文介绍了在Silverlight应用程序中实现数据验证的传统方法及使用数据绑定的方式,并探讨了客户端数据验证的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传统的验证方法

  开发应用程序最基本的的工作内容是进行数据验证。Silverlight的应用程序也不例外。Silverlight应用一定程度上类似于Windows Form应用。其数据验证可以用Winform传统的方法,如在准备提交时的代码中逐项检查数据的合法性。例如一个窗体中有若干输入框,和一个提交按钮。输入完毕后,点击提交按钮。我们可以在提交按钮Click事件处理程序中检查每个输入框的输入合法性。如果不合法,或者用一个弹出窗口提示用户,或者用别的一些方式(这些方式很多的,完全取决于UI设计),再之后就将光标停到有非法值的输入框,等待用户更正。

例如下面的代码:


  
< UserControl
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:navigation
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:uriMapper
="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk
="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
x:Class
="SilverlightApplication1.MainPage"
mc:Ignorable
="d" d:DesignWidth ="640" d:DesignHeight ="480" >
< Grid Height ="480" x:Name ="grid1" Width ="640" >
< sdk:Label Height ="19" x:Name ="label1" Width ="52" Content ="学生姓名" HorizontalContentAlignment ="Left" HorizontalAlignment ="Left" Margin ="32,113,0,0" VerticalAlignment ="Top" />
< TextBox Height ="23" x:Name ="textBox1" Width ="110" HorizontalAlignment ="Left" Margin ="109,109,0,0" HorizontalContentAlignment ="Left" VerticalAlignment ="Top" />
< Button Content ="打印" Height ="24" x:Name ="button1" Click ="button1_Click" Margin ="43,233,0,0" VerticalAlignment ="Top" HorizontalAlignment ="Left" Width ="70" />
< ComboBox Height ="24" HorizontalAlignment ="Left" Margin ="109,147,0,0" x:Name ="comboBox1" VerticalAlignment ="Top" Width ="110" >
< ComboBoxItem Content ="男" />
< ComboBoxItem Content ="女" />
</ ComboBox >
< sdk:Label Content ="性别" Height ="19" HorizontalAlignment ="Left" HorizontalContentAlignment ="Left" Margin ="32,147,0,0" x:Name ="label2" VerticalAlignment ="Top" Width ="52" />
< sdk:Label Height ="32" HorizontalAlignment ="Left" Margin ="68,35,0,0" x:Name ="label3" VerticalAlignment ="Top" Width ="141" Content ="学生档案管理" FontSize ="16" />
< Button Content ="保存" Height ="23" Margin ="134,233,0,0" x:Name ="button2" VerticalAlignment ="Top" Click ="button2_Click" HorizontalAlignment ="Left" Width ="75" />
</ Grid >
</ UserControl >

cs代码:


  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Printing;

namespace SilverlightApplication1
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}

void pDoc_PrintPage( object sender, PrintPageEventArgs e)
{
e.PageVisual
= this ;
// throw new NotImplementedException();
}

private void button1_Click( object sender, RoutedEventArgs e)
{
PrintDocument pDoc
= new PrintDocument();
pDoc.PrintPage
+= new EventHandler < PrintPageEventArgs > (pDoc_PrintPage);
pDoc.Print(
" 打印本页 " );
}

private void button2_Click( object sender, RoutedEventArgs e)
{
if (textBox1.Text.Length == 0 )
{
MessageBox.Show(
" 学生姓名必须输入 " );
textBox1.Focus();
}
}

private void grid1_Loaded( object sender, RoutedEventArgs e)
{
grid1.DataContext
= new StudentInfo();
}
}
}

这个验证是检查学生姓名是否输入了。如果没有输入就弹出一个消息窗口,要求输入学生姓名。如图:

image

再之后将光标定位到学生姓名输入框。这是最传统的Winform输入验证。我们还是可以沿用。

用数据绑定的方式来验证数据

  除了传统的方法之外,微软还提供了另外一种方式来实现数据合法性的验证,即:用客户端数据绑定来验证输入的数据。下面介绍一下。通过定义实现接口INotifyPropertyChanged的数据对象,来实现数据验证。

  首先创建数据对象,这个数据对象必须有get和set。


  
using System;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightApplication1
{
public class StudentInfo : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private string _name = null ;
private byte _gender = 0 ;

public string Name
{
get
{
return _name;
}
set
{
if ( string .IsNullOrEmpty(value))
throw new ArgumentException( " Student Name is required. " );
if (value.Length < 30 )
throw new ArgumentException( " Student Name is too long. " );
_name
= value;
OnPropertyChanged(
" name " );
}
}

public byte Gender
{
get
{
return _gender;
}
set
{
_gender
= value;
OnPropertyChanged(
" gender " );
}
}

private void OnPropertyChanged( string propertyName)
{
PropertyChanged(
this , new PropertyChangedEventArgs(propertyName));
}
}
}

编译一下。保证编译成功。这对后面的只能提示有用。切记。
XAML页面修改如下:


  
< UserControl
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:navigation
="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:uriMapper
="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk
="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:local ="clr-namespace:SilverlightApplication1"
x:Class
="SilverlightApplication1.MainPage"
mc:Ignorable
="d" d:DesignWidth ="640" d:DesignHeight ="480" >
< Grid Height ="480" x:Name ="grid1" Width ="640" Loaded ="grid1_Loaded" >
< Grid.DataContext >
< local:StudentInfo />
</ Grid.DataContext >
< sdk:Label Height ="19" x:Name ="label1" Width ="52" Content ="学生姓名" HorizontalContentAlignment ="Left" HorizontalAlignment ="Left" Margin ="32,113,0,0" VerticalAlignment ="Top" />
< TextBox Height ="23" x:Name ="textBox1" Width ="110" HorizontalAlignment ="Left" Margin ="109,109,0,0" HorizontalContentAlignment ="Left" VerticalAlignment ="Top" Text =" {Binding Mode=TwoWay, UpdateSourceTrigger=Explicit, NotifyOnValidationError=True, ValidatesOnExceptions=True, Path=Name} " />
< Button Content ="打印" Height ="24" x:Name ="button1" Click ="button1_Click" Margin ="43,233,0,0" VerticalAlignment ="Top" HorizontalAlignment ="Left" Width ="70" />
< ComboBox Height ="24" HorizontalAlignment ="Left" Margin ="109,147,0,0" x:Name ="comboBox1" VerticalAlignment ="Top" Width ="110" >
< ComboBoxItem Content ="男" />
< ComboBoxItem Content ="女" />
</ ComboBox >
< sdk:Label Content ="性别" Height ="19" HorizontalAlignment ="Left" HorizontalContentAlignment ="Left" Margin ="32,147,0,0" x:Name ="label2" VerticalAlignment ="Top" Width ="52" />
< sdk:Label Height ="32" HorizontalAlignment ="Left" Margin ="68,35,0,0" x:Name ="label3" VerticalAlignment ="Top" Width ="141" Content ="学生档案管理" FontSize ="16" />
< Button Content ="保存" Height ="23" Margin ="134,233,0,0" x:Name ="button2" VerticalAlignment ="Top" Click ="button2_Click" HorizontalAlignment ="Left" Width ="75" />
</ Grid >
</ UserControl >

  

笔者看英文的书中介绍是用Express Blend来写黄色和蓝色背景部分。笔者试了一下,在Visual Studio里面似乎没有和Blend一样的操作界面。但是不想为了这个功能来装一个Blend。这里介绍一个只用Visual Studio就能实现的方法:

首先找到需要绑定的控件的容器,这里我们想把学生姓名绑定到textBox1,textBox1的容器是grid1。那么在这一行后回车:

输入<Grid.DataContext>,回车

再输入<local:,Visual Studio智能提示,我们从中选择StudentInfo,在输入/>。然后就成了:


  
< Grid.DataContext >
< local:StudentInfo />
</ Grid.DataContext >

在容器添加数据上下文之后。在找到textBox1的Text属性。选”Appy Data Binding”.

image

Source这一页,StudentInfo已经作为DataContext,什么都不用变。点Path页,

image

选择Name,这里没有Converter,就直接选择Options页。

image

Mode选TwoWay,UpdateSourceTrigger选:Explicit,勾选NotifiyOnValidationError,ValidatesOnExceptions, ValidateOnNotifyDataErrors。

image

然后形成了上述XAML的蓝色背景部分。

 

之后再选grid1,加入grid1_Loaded处理程序。


  
private void grid1_Loaded( object sender, RoutedEventArgs e)
{
grid1.DataContext
= new StudentInfo();
}

这是给grid1的DataContext初始化一个数据对象。

再在保存按钮的click时间处理程序中如此写:


  
private void button2_Click( object sender, RoutedEventArgs e)
{
var bindingExpression
= textBox1.GetBindingExpression(TextBox.TextProperty);
bindingExpression.UpdateSource();
}

这是将textBox1的Text属性绑定到数据对象。
至此,我们可以运行此程序看看效果。因我们现在用的方法是在Set中抛出Exception。不能用Debug模式运行。请用Debug->Start without Debugging来启动程序。

姓名是必须输入的,试试不输入,直接点保存,姓名输入框会有一个红框:

image

鼠标移到其右上角的小三角处。

数据对象中抛出的Exception信息就会显示出来:

image

至此已经实现了一种根据数据对象绑定到Silverlight控件的数据验证方法。以上是在Set抛出例外的方法。

微软还为我们实现了一种DataAnnotation的机制。这样需要我们的工程引用System.ComponentModel.DataAnnotations.dll。还要加上:


  
using System.ComponentModel.DataAnnotations;

 
如下代码:

  
[Required(ErrorMessage = " 请输入学生姓名 " )]
public string Name
{
get
{
return _name;
}
set
{
var validatorContext
= new ValidationContext( this , null , null );
validatorContext.MemberName
= " Name " ;
Validator.ValidateProperty(value, validatorContext);

_name
= value;

}
}
又如加一个最长30个字符的限制:

 

  
[Required(ErrorMessage = " 请输入学生姓名 " )]
[StringLength(
30 , ErrorMessage = " 最长30个字符 " )]
public string Name
{
get
{
return _name;
}
set
{
var validatorContext
= new ValidationContext( this , null , null );
validatorContext.MemberName
= " Name " ;
Validator.ValidateProperty(value, validatorContext);

_name
= value;

}
}
image

以上是DataAnnotation方法来做输入验证。

Silverlight数据验证的安全性

  上面说了这么些数据验证方法。都是在客户端浏览器里运行的验证程序。都是不安全的。Silverlight程序就象Javascript程序一样在客户端浏览器中运行。黑客可以解开xap包,修改Silverlight程序。这和黑客可以绕过Javascript是一样的道理。所以基于Silverlight的系统,都必须在服务器端的WCF和web应用中加入严格的数据验证。才能真正保证安全。


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值