Silverlight的数据验证Input validation

传统的验证方法

  开发应用程序最基本的的工作内容是进行数据验证。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();
}
}
}

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

再之后将光标定位到学生姓名输入框。这是最传统的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”.

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

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

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

然后形成了上述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来启动程序。

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

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

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

至此已经实现了一种根据数据对象绑定到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;

}
}

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

Silverlight数据验证的安全性

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



 

时间: 2024-09-22 12:28:27

Silverlight的数据验证Input validation的相关文章

Silverlight3系列(六)数据验证 Data Validation

本篇我们讨论SL3中的数据验证相关知识. 数据验证只会发生双向绑定的情况下,因为实体类需要实现INotifyPropertyChanged接口.在SL中数据绑定的时候如果遇到没有验证的数据,通常会忽略它.下面的表中,列出在双向绑定的时候,三种类型的错误: 1.不正确的数据.例如:本来是应该数字类型的,不应该输入字符或者其他字符,同时,也不能超出最大值. 2.对象属性的set异常.例如:在属性Id的set中有一个判断,如果有问题就抛出异常. 3.只读属性,你不能进行赋值操作. 如果是上面的错误,你

Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例

C++中正则表达式 的 子表达式(subexpressions) 的数据验证

子表达式(subexpressions)的 数据验证(data validation), 可以通过括号"()"分解正则表达式的子表达式; 然后使用下标标示符[], 输出相应的子表达式, "0"代表全体, "1"代表第一个括号, 依次递加; 通过对于问号项?是否匹配, 验证正则表达式的匹配式; 代码: #include <iostream> #include <string> #include <boost/regex

Swing通用数据验证模块

这段时间真是忙得要死,一方面要开发公司项目的系统框架,要将项目分成不同的子项目,编写核心 代码:另一方面要将极限编程(XP)引入团队开发,部署各类 XP需要的服务例如subversion啦,ant+ivy 啦,Hudson啦等等.顺便说句题外话,ubuntu还真是不是一般的好用,建议有能力的全部转到ubuntu上去 开发. 我目前开发的这个框架的客户端是具肥的客户端,也就是Swing客户端了.Swing应用相对于Web应用有 很多优势,因为它更肥.数据验证就是其中一个.当然现在的Web应用通过使

Silverlight实例教程 - Validation数据验证开篇

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation 数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation 服务器端异步数据验证 Silverlight

Silverlight实例教程 - Validation用户提交数据验证捕获

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例

silverlight Validation MVVM下用户提交数据验证捕获

转自http://www.cnblogs.com/HalfwayMonk/archive/2011/01/08/1930495.html @jv9的数据验证系列文章:Silverlight实例教程Validation验证系列中已经详细介绍了silverlight下的各种数据验证的方法.我也看着这些文章学习过来的. 现在在实践MVVM,需要在MVVM下实现提交数据验证,一步一步来. 参考系列文章的第四篇,定义一个验证的基类实现:INotifyPropertyChanged和IDataErrorIn

Silverlight实例教程 - Validation服务器端异步数据验证

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例

Silverlight实例教程 - Validation客户端同步数据验证

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation服务器端异步数据验证 Silverlight实例