无论是客户端验证与否,都应该执行服务器验证。用户可能会禁用javascript,或者做一些意想不到的事情来绕过客户端验证,而服务器是保护数据、防止劣质输入的最后一道防线。有些验证规则也需要服务器进行处理。下面我们来讲讲服务器验证。
服务器验证包括两种,利用data annotations注解属性修身字段
一、data annotations验证
using System.ComponentModel.DataAnnotations;//必须要引进此命名空间
public class CompanyInput
{
[Display(Name="公司名")]
[Required(ErrorMessage = "{0}是必需的")]
public string CompanyName { get; set; }
[EmailAddress(ErrorMessage="邮箱格式有误!")]
public string EmailAddress { get; set; }
}
我们适用男RequiredAttribute修饰了CompanyName属性EmailAddressAttribute修饰了EmailAddress属性。那么我们只需在视图中添加相应的语句就实现了一个简单的验证。
@model Web.Models.CompanyInput
@{
ViewBag.Title = "Edit - Server Side Validation";
}
<h2>Edit</h2>
@using (Html.BeginForm("Edit", "Home")) {
@Html.TextBoxFor(u => u.CompanyName);
@Html.ValidationMessageFor(u=>u.CompanyName)//当输入为空的时候,提示公司名不能为空
@Html.TextBoxFor(u => u.EmailAddress);
@Html.ValidationMessageFor(u => u.EmailAddress);//必须以邮件的形式输入,如果格式不正确,会有提示信息
<button type="submit">Submit</button>
}
这就完成了一次验证
效果如下:
二、自定义服务器端验证(扩展ModelMetadataProvider)
asp.net mvc 中的许多新特性都使用模型元数据。模板使用模型元数据来显示input元素和显示文本,而验证提供器则使用模型元数据来执行验证。如果我们希望其他资源而不是DataAnnotaions来填充模型元数据,则需要通过ModelMetadataProvider进行派生。
displaynameAttribute注解属性可以用来显示验证错误信息和输入标签显示的名称。如上图的commanyName。我们总是习惯commanyname之间是有空格的。所以我们可以扩展modelMetadataProvider类,以实现自动带空格。如下:
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Validation;
using System.Text.RegularExpressions;
namespace Web
{
public class ConventionProvider :
DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
var meta = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if (meta.DisplayName == null)
meta.DisplayName = meta.PropertyName.ToSeparatedWords();
return meta;
}
}
public static class StringExtensions
{
public static string ToSeparatedWords(this string value)
{
if (value != null)
return Regex.Replace(value, "([A-Z][a-z]?)", " $1").Trim();
return null;
}
}
}
然后再Global.asax文件中重新配置一下
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.EnableDefaultBundles();
ModelMetadataProviders.Current = new ConventionProvider();//加这一句
}