使用 RIA 和 Entity Framework 在 Silverlight 中进行数据绑定 - 第 3 部分(验证输入数据)





0/5 (0投票)
使用 RIA 和 Entity Framework 在 Silverlight 中进行数据绑定 - 验证输入数据
验证是软件开发中不可或缺的一部分。在 Silverlight 中,验证方法已经发生改变,或者说,它已从 2.0 版本发展至今。因此,本文将继续以 StatesOfIndia
应用程序为例,重点介绍可用的验证选项。
文章系列
- Silverlight With RIA and Entity Framework 数据绑定 – 第 1 部分(显示数据)
- Silverlight With RIA and Entity Framework 数据绑定 – 第 2 部分(编辑/更新数据)
- 使用 RIA 和 Entity Framework 在 Silverlight 中进行数据绑定 - 第 3 部分(验证输入数据)
扩展 StatesOfIndia 应用程序
在 SOI 应用程序的基础上,我们将为用户输入添加验证。总的来说,我想为以下逻辑添加验证:
基本验证
- 州名必填,长度不能超过 15 个字符
- 人口、识字率、区数、面积的数据类型验证,只允许输入数字
- 网站 URL 验证
- 定义人口、识字率的范围
高级验证
- 交叉检查州名是否在数据库中存在(跨属性验证)
RIA With Silverlight 验证
验证用户输入的方法有很多。您可以选择在客户端进行,无需服务器往返或请求;也可以选择在服务器端进行;或者进行异步验证。这取决于您的选择和场景。Silverlight 的早期版本主要依赖于基于异常的验证,而当前可用的解决方案,讨论它没有意义,因此我跳过了基于异常的验证。
Silverlight 4 主要公开了以下几种验证方法:
- 使用元数据属性
- 代码隐藏方法(可在客户端使用异步操作,或者仅在服务器端使用)
使用属性元数据
如前所述,验证规则可以在实体级别及其成员上定义。为此,请确保在添加 DomainService
时选择了元数据生成选项。此选项将添加一个元数据类“DomainService_SOI.metadata.cs”。检查类文件,我们可以找到实体及其成员。
![]() | ![]() |
现在,假设我想强制 stateName
必填,并且州名长度不能超过 15
个字符,那么:
[Required(AllowEmptyStrings=false,ErrorMessage="State Name cannot be empty")]
[StringLength(15)]
public string StateName { get; set; }
现在构建您的应用程序,并在客户端 Silverlight 项目中检查生成的代码。
传播的客户端验证代码
/// <summary>
/// Gets or sets the ‘StateName’ value.
/// </summary>
[DataMember()]
[Required(ErrorMessage="State Name cannot be empty")]
[StringLength(15)]
public string StateName
{
get
{
return this._stateName;
}
set
{
if ((this._stateName != value))
{
this.OnStateNameChanging(value);
this.RaiseDataMemberChanging(“StateName”);
this.ValidateProperty(“StateName”, value);
this._stateName = value;
this.RaiseDataMemberChanged(“StateName”);
this.OnStateNameChanged();
}
}
}
如果您注意到,您会发现我们添加到模型元数据成员的属性会自动传播到客户端。我们可以通过提供 Error Message 属性来显示自定义错误消息,如下所示:
[Required(AllowEmptyStrings=false,ErrorMessage="State Name cannot be empty")]
System.ComponentModel.DataAnnotations
命名空间中用于属性级别验证的其他一些属性如下:
- DataTypeAttribute
- DisplayAttribute
- RangeAttribute
- RegularExpressionAttribute
- StringLengthAttribute 和其他属性,请参阅 详细列表。
因此,如上所述,SOI 应用程序的基本验证可以使用以下属性来实现。
州名必填,长度不能超过 15 个字符
[Required(AllowEmptyStrings=false,ErrorMessage="State Name cannot be empty")]
[StringLength(15)]
public string StateName { get; set; }
由于需要在文本框失去焦点时触发验证,我们需要做一些前期准备工作,尽管不情愿 :),请查看我上次的 博文。
网站 URL 验证
[DataType(DataType.Url)]
public string Website { get; set; }
定义人口、识字率的范围
[Range(0,100)]
public Nullable<int> Literacy { get; set; }
人口、识字率、区数、面积的数据类型验证,只允许输入数字。由于我们需要限制用户输入的值,我在代码隐藏的 KeyDown
事件中进行了处理。
自定义属性验证
虽然默认属性提供了几乎所有标准的验证方式,但有时自定义验证是不可避免的。例如,这里维基信息内容必须超过 3 个词。要添加自定义验证,请牢记以下几点:
- 添加一个类,其中包含服务器端的验证逻辑
- 确保您的类具有 shared.cs 扩展名,以便验证可以传播到客户端
我们来做。在解决方案的服务器端项目添加类 StateValidations.shared.cs。
自定义验证检查是一个简单的 C# 代码,名为“ValidInfo
”,它是一个 static
成员,除了要检查的值之外,还接受 ValidationContext 作为参数。ValidationContext
代表要验证的对象的状态和服务。一旦验证成功,它将返回一个 ValidationResult 对象。
namespace StatesOfIndia.Web.Shared
{
public class StateValidations
{
public static ValidationResult ValidInfo(string description, ValidationContext context)
{
//Validation Logic
if (String.IsNullOrEmpty(description))
{
return ValidationResult.Success;
}
string[] words = description.Split(new char[] { ‘ ‘, ‘\t’, ‘\n’, ‘\r’, },
StringSplitOptions.RemoveEmptyEntries);
if (words.Length > 3)
{
return ValidationResult.Success;
}
//return Validation Error
return new ValidationResult(“The Wiki Info must be meaningful.”,
new string[] { “WikiIntro” });
}
}
}
项目构建后,在 Silverlight 客户端项目中检查。生成的代码存根现在将具有相同的 shared.cs。
为了实现自定义验证器,让我们移至服务器端项目中的 TasksDomainService.metadata.cs 文件,并为 WikiInfo
属性添加以下属性:
[CustomValidation(typeof(StateValidations),"ValidInfo")]
public string WikiIntro { get; set; }
当 CustomValidation 属性应用于属性时,该属性将在每次为该属性赋值时调用。当它应用于方法时,该属性将在每次程序调用该方法时调用。当它应用于方法参数时,该属性将在方法调用之前调用。更详细的文章可以在 这里 找到。
让我们运行应用程序并查看结果。
异步验证以检查州名是否在数据库中存在
在 SOI 应用程序中,在将 State
添加到集合之前检查它是否在数据库中存在是很常见的。与其在点击按钮时进行验证,不如在用户离开州名 Textbox
时即时进行验证会更好。为了使验证成功,它需要回溯到数据库集合并进行验证。
哦,这相当令人兴奋。我们来看看。
- 在域服务类“DomainService_SOI.cs” 中添加一个新的方法/操作,命名为“
IsStateExist
”。如下所示,该方法具有 [INVOKE
] 属性,该属性允许操作在没有延迟执行的情况下运行。有关更多详细信息,请参阅 此处。)[Invoke] //Custom Validation for Async Operation public bool IsStateExist(string stateName) { bool isStateExist = false; isStateExist = GetStates().Any(state => state.StateName == stateName); return isStateExist; }
- 添加一个自定义验证器方法作为共享代码,就像我们在上面的“
ValidInfo
”案例中所做的那样。public static ValidationResult AsyncValidateState(string stateName, ValidationContext valContext) { ValidationResult error = new ValidationResult( “State with specified name already exists”, new string[] { valContext.MemberName }); //Code For Client Side silverlight project #if SILVERLIGHT DomainService_SOI context = new DomainService_SOI(); InvokeOperation<bool> IsExist = context.IsStateExist(stateName); IsExist.Completed += (s, e) => { if (!IsExist.HasError && IsExist.Value) { Entity entity = (Entity)valContext.ObjectInstance; entity.ValidationErrors.Add(error); } }; #endif return ValidationResult.Success; }
- 然后,在元数据代码中添加 CustomValidation 属性。
[CustomValidation(typeof(StateValidations), "AsyncValidateState")] public string StateName { get; set; }
让我们运行应用程序,让验证发挥作用。
结论
希望这篇文章能让你对数据验证有一个清晰的认识。继续学习 :)。