zoukankan      html  css  js  c++  java
  • 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();
    }
    }
    }

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

    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应用中加入严格的数据验证。才能真正保证安全。

    

     
  • 相关阅读:
    wpf
    UseFul Collection
    关于一些程序中用到的新方法与拓展
    冒泡排序
    学习java的第三天,猜字符的小程序
    ThinkPHP中,运用PHPExcel,将数据库导出到Excel中
    关于maven下,lombok的安装
    关于windows下activeMQ的安装
    关于windows下redis的安装
    find 练习
  • 原文地址:https://www.cnblogs.com/mikelij/p/1959140.html
Copyright © 2011-2022 走看看