构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(33)-数据验证共享

原文:构建ASP.NET
MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(33)-数据验证共享

注:本节阅读需要有MVC
自定义验证的基础,否则比较吃力

一直以来表单的验证都是不可或缺的,微软的东西还是做得比较人性化的,从webform到MVC,都做到了双向验证

单单的用js实现的前端验证是极其不安全的,所以本次我们来看看MVC上的自带的注解验证,自定义验证

同样的MVC提供了一系列内置的数据验证注解

  1. 不为空验证  [Required(ErrorMessage = "不能为空")]

  2. 长度验证     [StringLength(10, MinimumLength = 2)]

  3. 取值范围     [Range(1, 3)]

  4. 类型验证  
      [DataType(DataType.Date)]

  5. 正则表达  
      [RegularExpression(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+/.[A-Za-z]{2,4}”)]
      Email Demo

  6. 远程验证     [Remote("CheckUserNameExists",
    "ValidationDemo", ErrorMessage = "用户名已存在")]

  7. 请求验证     [AllowHtml]
    允许传入HTML

  8. 等等.....

MVC3项目模板自带的登录模型类如下:


public class LogOnModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }

[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }

[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}

MVC3自带的模板项目中已经有了:

<add key="ClientValidationEnabled" value="true"/>
<add
key="UnobtrusiveJavaScriptEnabled" value="true"/>

然后在被验证的View页面上要参加如许两个JavaScript,重视,他们是依附于JQuery的:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
type="text/javascript"></script>
<script
src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
type="text/javascript"></script>

验证消息的显示有两种,一种是ValidationSummary,它可以显示一份验证消息的汇总,包含从后台Action里返回的消息。

@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the
errors and try again.")
另一种是Model中各属性对应HTML控件的验证消息:

@Html.ValidationMessageFor(m => m.UserName)

所以要前端代码有验证效果必须引入jquery库

但是往往系统自带的验证是远远满足不了我们的,我们需要更加灵活的封装,不可能我要验证数字是否填了
0-9之间都要去写一个表表达式吧,还好官方也灵活的提供了扩展,自定义验证。

自定义验证我就不多说了,在园里搜索一下就很多原理及编写方法。这里我为大家共享一个常用的自定验证

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Globalization;
using System.Web.Security;
using System.Text.RegularExpressions;

namespace App.Models
{
/** 使用说明
* 继承 ValidationAttribute 抽象类,重写 IsValid() 方法,以实现服务端验证
* 实现 IClientValidatable 接口的 GetClientValidationRules() 方法,以实现客户端验证
*
* 1. [IntRangeExpression(18, 30)] 数字在18与30之间,可以不填写,但填写就进入验证
* 2. [MaxWordsExpression(50)] 字符数在不能大50,可以不填写,但填写就进入验证
* 3. [NotNullExpression] 验证是否为空且 调用
* 4. [DateExpression] 是否是日期格式:2012-10-1
* 5. [IsCharExpression] 只能是数字,字母,下划线,中划线组成,可以不填写
* 6. [ChinaCharExpression] 只能输入汉字,可以不填写
* 7. [NotEqualExpression("abcd")] 不能等于指定的值,可以不填写:如不能等于abcd
* 8. [ContainExpression("abc")] 验证是否包含指定字符串,可以不填写:如必须包含abc
* 9. [NotContainExpression("abc")] 验证不能指定字符串,可以不填写,如不能含有abc
*10. [IsIntegerEpression] 验证是否是数字格式 可以不填写,可以为任意整数 1,-5
*11. [IsPositiveIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意正整数 25
*12. [IsNegativeIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意负整数 -25
*13. [IsDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意浮点数 12.12,12,-12.12
*14. [IsPositiveDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意正浮点数 1.4
*15. [IsNegativeDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意负浮点数 -1.2
*16. [EmailExpression] 验证是否是Email
*17. [PhoneExpression] 验证是否是中国电话号码 如:0769-222222-222 正确格式为:"XXX-XXXXXXX"、"XXXX- XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
*18. [SiteExpression] 验证是否是一个完整的网址 如:www.163.com
*19. [IsNumberExpression] 验证是否是数字格式 可以不填写,可以为任意数字
*
*
* 组合使用演示
* [DisplayName("姓名")] 名称
* [NotNullExpression] 不能为空
* [MaxWordsExpression(50)] 最多50个字符,25个汉字
* [IsCharExpression] 只能由数字,字母,中划线,下划线组成(一般用于验证ID)
* [NotEqualExpression("admin")] 不能包含有admin字符串
* public string Id { get; set; }
*
* 数字判断演示
* [IsNumberExpression] 可以不填写,填写判断是否是数字
* [DisplayName("代号")]
* public int? age { get; set; }
* 非空字断使用
* //[Required(ErrorMessageResourceType = typeof(ErrorRs), ErrorMessageResourceName = "IsNumberExpression")]
* 或//[Required(ErrorMessage="必须填写这个字段")] 来覆盖本地化 如public int age; int?为可空字端
**/
/// <summary>
/// [IntRangeExpression(18, 30)] 数字在18与30之间,可以不填写,但填写就进入验证
/// </summary>
public class IntRangeExpressionAttribute : ValidationAttribute, IClientValidatable
{
long minMum { get; set; }
long maxMum { get; set; }
public IntRangeExpressionAttribute(long minimum, long maximum)
{
minMum = minimum;
maxMum = maximum;
}

public override bool IsValid(object value)
{
if (value == null)
return true;
long intValue = Convert.ToInt64(value);
return intValue >= minMum && intValue <= maxMum;
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须在{1}和{2}之间", name, minMum, maxMum);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule validationRule = new ModelClientValidationRule()
{
ValidationType = "isinteger",
ErrorMessage = FormatErrorMessage(metadata.DisplayName)
};
// 向客户端验证代码传递参数
validationRule.ValidationParameters.Add("param1", minMum);
validationRule.ValidationParameters.Add("param2", maxMum);
yield return validationRule;
}
}
/// <summary>
/// [MaxWordsExpression(50)]字符数在不能大50,可以不填写,但填写就进入验证
/// </summary>
public class MaxWordsExpressionAttribute : ValidationAttribute, IClientValidatable
{

int maxStr { get; set; }
public MaxWordsExpressionAttribute(int maximum)
{
maxStr = maximum;
}

public override bool IsValid(object value)
{
if (value == null)
return true;
string valueAsString = value.ToString();

return (Encoding.Default.GetByteCount(valueAsString) <= maxStr);

}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}最多{1}个汉字,{2}个字符", name, maxStr / 2, maxStr);

}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule validationRule = new ModelClientValidationRule()
{
ValidationType = "maxwords",
ErrorMessage = FormatErrorMessage(metadata.DisplayName)
};
validationRule.ValidationParameters.Add("param", maxStr);
yield return validationRule;
}
}

/// <summary>
/// [MinWordsExpression(50)]字符数在不能少于50个字符,可以不填写,但填写就进入验证
/// </summary>
public class MinWordsExpressionAttribute : ValidationAttribute, IClientValidatable
{

int minStr { get; set; }
public MinWordsExpressionAttribute(int minimum)
{
minStr = minimum;
}

public override bool IsValid(object value)
{
if (value == null)
return true;
string valueAsString = value.ToString();

return (Encoding.Default.GetByteCount(valueAsString) >= minStr);

}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}最少{1}个字符", name, minStr);

}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule validationRule = new ModelClientValidationRule()
{
ValidationType = "minwords",
ErrorMessage = FormatErrorMessage(metadata.DisplayName)
};
validationRule.ValidationParameters.Add("param", minStr);
yield return validationRule;
}
}
/// <summary>
/// [NotNullExpression] 验证是否为空且不能有空格 调用
/// </summary>
public class NotNullExpressionAttribute : ValidationAttribute, IClientValidatable
{
static string DispalyName = "";
public NotNullExpressionAttribute()
: base("{0}必须填写")
{
}
public override string FormatErrorMessage(string name)
{
return String.Format(name, DispalyName);
}

public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
string valueAsString = value.ToString();
bool result = !string.IsNullOrEmpty(valueAsString);
return result;

}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
DispalyName = metadata.DisplayName;
return new[]{
new ModelClientValidationRequiredRule(FormatErrorMessage("{0}必须填写"))
};
}
}
/// <summary>
/// [DateExpression] 是否是日期格式:2012-10-1
/// </summary>
public class DateExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"((^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(10|12|0?[13578])([-\/\._])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(11|0?[469])([-\/\._])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\._])(0?2)([-\/\._])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\/\._])(0?2)([-\/\._])(29)$)|(^([3579][26]00)([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][0][48])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][0][48])([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][2468][048])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][2468][048])([-\/\._])(0?2)([-\/\._])(29)$)|(^([1][89][13579][26])([-\/\._])(0?2)([-\/\._])(29)$)|(^([2-9][0-9][13579][26])([-\/\._])(0?2)([-\/\._])(29)$))";
public DateExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
string valueAsString = value.ToString();
string dtvalue;
if (value.ToString().IndexOf(" ") > 0)
{
dtvalue = valueAsString.Replace("/", "-").Substring(0, valueAsString.IndexOf(" "));
}
else
{
dtvalue = valueAsString.Replace("/", "-");
}
Match mch = reg.Match(dtvalue);
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是日期格式:2012-10-10", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [IsCharExpression] 只能是数字,字母,下划线,中划线组成,可以不填写
/// </summary>
public class IsCharExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^[0-9A-Za-z_-]{0,}$";
public IsCharExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}由字母,数字,划线,划线组成", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [ChinaCharExpression] 只能输入汉字,可以不填写
/// </summary>
public class ChinaCharExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^[\u4e00-\u9fa5]{0,}$";
public ChinaCharExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}只能填写汉字", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [NotEqualExpression("abcd")],不能等于指定的值,可以不填写:如不能等于abcd
/// </summary>
public class NotEqualExpressionAttribute : ValidationAttribute, IClientValidatable
{
string InputString { get; set; }
public NotEqualExpressionAttribute(string inputString)
{
InputString = inputString;
}

public override bool IsValid(object value)
{
if (value == null)
return true;
string valueAsString = value.ToString();

return (valueAsString != InputString);

}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}不能等同于{1}", name, InputString);

}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule validationRule = new ModelClientValidationRule()
{
ValidationType = "notequal",
ErrorMessage = FormatErrorMessage(metadata.DisplayName)
};
validationRule.ValidationParameters.Add("param", InputString);
yield return validationRule;
}
}
/// <summary>
/// [ContainExpression("abc")] 验证是否包含指定字符串,可以不填写:如必须包含abc
/// </summary>
public class ContainExpressionAttribute : ValidationAttribute, IClientValidatable
{
string InputString { get; set; }
public ContainExpressionAttribute(string inputString)
{
InputString = inputString;
}

public override bool IsValid(object value)
{
if (value == null)
return true;
string valueAsString = value.ToString();
return (valueAsString.Contains(InputString));
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须不能包含字符串:{1}", name, InputString);

}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule validationRule = new ModelClientValidationRule()
{
ValidationType = "contain",
ErrorMessage = FormatErrorMessage(metadata.DisplayName)
};
validationRule.ValidationParameters.Add("param", InputString);
yield return validationRule;
}
}
/// <summary>
/// [NotContainExpression("abc")],验证不能指定字符串,可以不填写,如不能含有abc
/// </summary>
public class NotContainExpressionAttribute : ValidationAttribute, IClientValidatable
{
string InputString { get; set; }
public NotContainExpressionAttribute(string inputString)
{
InputString = inputString;
}

public override bool IsValid(object value)
{
if (value == null)
return true;
string valueAsString = value.ToString();
return (!valueAsString.Contains(InputString));
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须不能包含字符串:{1}", name, InputString);

}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule validationRule = new ModelClientValidationRule()
{
ValidationType = "notcontain",
ErrorMessage = FormatErrorMessage(metadata.DisplayName)
};
validationRule.ValidationParameters.Add("param", InputString);
yield return validationRule;
}
}
/// <summary>
/// [IsNumberExpression] 验证是否是数字格式,可以不填写,必须是任意数字
/// </summary>
public class IsNumberExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^[-]?\d+(\.\d+)?$";
public IsNumberExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
string input = value.ToString();
Match mch = reg.Match(input);
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是一个数字", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [IsIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意整数 -1,1
/// </summary>
public class IsIntegerExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^-?\d+$";
public IsIntegerExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是一个整数", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}

/// <summary>
/// [IsPositiveIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意正整数 25
/// </summary>
public class IsPositiveNumberExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^\d+$";
public IsPositiveNumberExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是一个正整数", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [IsNegativeIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意负整数 -25
/// </summary>
public class IsNegativeNumberExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^-?\d+$";
public IsNegativeNumberExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是一个负整数", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [IsDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意浮点数 12.12,12,-12.12
/// </summary>
public class IsDecimalExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^[-]?\d+(\.\d+)?$";
public IsDecimalExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是一个浮点数", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [IsPositiveDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意正浮点数 1.4
/// </summary>
public class IsPositiveDecimalExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^\d+(\.\d+)?$";
public IsPositiveDecimalExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是一个浮正点数", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [IsNegativeDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意负浮点数 -1.2
/// </summary>
public class IsNegativeDecimalExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^-\d+(\.\d+)?$";
public IsNegativeDecimalExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是一个浮负点数", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [EmailExpression] 验证是否是Email
/// </summary>
public class EmailExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$";
public EmailExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是邮箱地址", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// [PhoneExpression] 验证是否是中国电话号码 如:0769-222222-222 正确格式为:"XXX-XXXXXXX"、"XXXX- XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
/// </summary>
public class PhoneExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"^((0\d{2,5}-)|\(0\d{2,5}\))?\d{7,8}(-\d{3,4})?$";
public PhoneExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}不是正确的电话号码,如:0769-2222222", name);
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}
/// <summary>
/// 验证是否是网址 调用[SiteExpression]
/// </summary>
public class SiteExpressionAttribute : RegularExpressionAttribute, IClientValidatable
{
static string regStr = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
public SiteExpressionAttribute()
: base(regStr)
{

}

public override bool IsValid(object value)
{
if (value == null)
return true;
Regex reg = new Regex(regStr);
Match mch = reg.Match(value.ToString());
if (mch.Success)
{
return true;
}
else
{
return false;
}
}

public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
"{0}必须是网址,如:http://www.google.com", name);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var name = metadata.GetDisplayName();
var rule = new ModelClientValidationRegexRule(FormatErrorMessage(name), Pattern);
yield return rule;
}
}

}

/* 双向验证,请加入以下代码

// [IntRangeExpression(18, 30)] 数字在18与30之间,可以不填写,但填写就进入验证
jQuery.validator.addMethod(‘isinteger‘, function (value, element, params) {
if (value >= parseInt(params[‘param1‘]) && value <= parseInt(params[‘param2‘]))
return true;
return false;
});
jQuery.validator.unobtrusive.adapters.add(‘isinteger‘, [‘param1‘, ‘param2‘],
function (options) {
options.rules[‘isinteger‘] = { param1: options.params.param1, param2: options.params.param2 };
options.messages[‘isinteger‘] = options.message;
}
);
// [MaxWordsExpression(50)]字符数在不能大50,可以不填写,但填写就进入验证
jQuery.validator.addMethod(‘checkMaxWords‘, function (value, element, param) {
if (strLen(value) > param)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘maxwords‘, [‘param‘],
function (options) {
options.rules[‘checkMaxWords‘] = { param: options.params.param };
options.messages[‘checkMaxWords‘] = options.message;
}
);
// [MinWordsExpression(50)]字符数在不能shaoyu 50,可以不填写,但填写就进入验证
jQuery.validator.addMethod(‘checkMinWords‘, function (value, element, param) {
if (strLen(value) < param)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘minwords‘, [‘param‘],
function (options) {
options.rules[‘checkMinWords‘] = { param: options.params.param };
options.messages[‘checkMinWords‘] = options.message;
}
);
// [NotEqualExpression("abcd")],不能等于指定的值,可以不填写:如不能等于abcd
jQuery.validator.addMethod(‘checkNotEqual‘, function (value, element, param) {
if (value == param)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘notequal‘, [‘param‘],
function (options) {
options.rules[‘checkNotEqual‘] = { param: options.params.param };
options.messages[‘checkNotEqual‘] = options.message;
}
);
// [ContainExpression("abc")] 验证是否包含指定字符串,可以不填写:如必须包含abc
jQuery.validator.addMethod(‘checkContain‘, function (value, element, param) {
if (value.indexOf(param) == -1)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘contain‘, [‘param‘],
function (options) {
options.rules[‘checkContain‘] = { param: options.params.param };
options.messages[‘checkContain‘] = options.message;
}
);

// [NotContainExpression("abc")],验证不能指定字符串,可以不填写,如不能含有abc
var v_checknotcontainReturn = "";
jQuery.validator.addMethod(‘checkNotContain‘, function (value, element, param) {
if (value.indexOf(param) != -1)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘notcontain‘, [‘param‘],
function (options) {
options.rules[‘checkNotContain‘] = { param: options.params.param };
options.messages[‘checkNotContain‘] = options.message;
}
);
*/


View
Code

双向验证引入JS,否则无法启用前端验证

//双向验证,请加入以下代码

// [IntRangeExpression(18, 30)] 数字在18与30之间,可以不填写,但填写就进入验证
jQuery.validator.addMethod(‘isinteger‘, function (value, element, params) {
if (value >= parseInt(params[‘param1‘]) && value <= parseInt(params[‘param2‘]))
return true;
return false;
});
jQuery.validator.unobtrusive.adapters.add(‘isinteger‘, [‘param1‘, ‘param2‘],
function (options) {
options.rules[‘isinteger‘] = { param1: options.params.param1, param2: options.params.param2 };
options.messages[‘isinteger‘] = options.message;
}
);
// [MaxWordsExpression(50)]字符数在不能大50,可以不填写,但填写就进入验证
jQuery.validator.addMethod(‘checkMaxWords‘, function (value, element, param) {
if (strLen(value) > param)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘maxwords‘, [‘param‘],
function (options) {
options.rules[‘checkMaxWords‘] = { param: options.params.param };
options.messages[‘checkMaxWords‘] = options.message;
}
);
// [MinWordsExpression(50)]字符数在不能shaoyu 50,可以不填写,但填写就进入验证
jQuery.validator.addMethod(‘checkMinWords‘, function (value, element, param) {
if (strLen(value) < param)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘minwords‘, [‘param‘],
function (options) {
options.rules[‘checkMinWords‘] = { param: options.params.param };
options.messages[‘checkMinWords‘] = options.message;
}
);
// [NotEqualExpression("abcd")],不能等于指定的值,可以不填写:如不能等于abcd
jQuery.validator.addMethod(‘checkNotEqual‘, function (value, element, param) {
if (value == param)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘notequal‘, [‘param‘],
function (options) {
options.rules[‘checkNotEqual‘] = { param: options.params.param };
options.messages[‘checkNotEqual‘] = options.message;
}
);
// [ContainExpression("abc")] 验证是否包含指定字符串,可以不填写:如必须包含abc
jQuery.validator.addMethod(‘checkContain‘, function (value, element, param) {
if (value.indexOf(param) == -1)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘contain‘, [‘param‘],
function (options) {
options.rules[‘checkContain‘] = { param: options.params.param };
options.messages[‘checkContain‘] = options.message;
}
);

// [NotContainExpression("abc")],验证不能指定字符串,可以不填写,如不能含有abc
var v_checknotcontainReturn = "";
jQuery.validator.addMethod(‘checkNotContain‘, function (value, element, param) {
if (value.indexOf(param) != -1)
return false;
return true;
});
jQuery.validator.unobtrusive.adapters.add(‘notcontain‘, [‘param‘],
function (options) {
options.rules[‘checkNotContain‘] = { param: options.params.param };
options.messages[‘checkNotContain‘] = options.message;
}
);

一共包含了19个常用验证及封装

* 1. [IntRangeExpression(18, 30)] 数字在18与30之间,可以不填写,但填写就进入验证
* 2.
[MaxWordsExpression(50)] 字符数在不能大50,可以不填写,但填写就进入验证
* 3.
[NotNullExpression] 验证是否为空且 调用
* 4. [DateExpression]
是否是日期格式:2012-10-1
* 5. [IsCharExpression]
只能是数字,字母,下划线,中划线组成,可以不填写
* 6. [ChinaCharExpression]
只能输入汉字,可以不填写
* 7. [NotEqualExpression("abcd")]
不能等于指定的值,可以不填写:如不能等于abcd
* 8. [ContainExpression("abc")]
验证是否包含指定字符串,可以不填写:如必须包含abc
* 9. [NotContainExpression("abc")]
验证不能指定字符串,可以不填写,如不能含有abc
*10. [IsIntegerEpression]
验证是否是数字格式 可以不填写,可以为任意整数 1,-5
*11.
[IsPositiveIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意正整数 25

*12. [IsNegativeIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意负整数 -25

*13. [IsDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意浮点数
12.12,12,-12.12
*14. [IsPositiveDecimalExpression]
验证是否是数字格式 可以不填写,可以为任意正浮点数 1.4
*15. [IsNegativeDecimalExpression]
验证是否是数字格式 可以不填写,可以为任意负浮点数 -1.2
*16. [EmailExpression]
验证是否是Email
*17. [PhoneExpression]
验证是否是中国电话号码 如:0769-222222-222 正确格式为:"XXX-XXXXXXX"、"XXXX-
XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
*18.
[SiteExpression] 验证是否是一个完整的网址 如:www.163.com

*19. [IsNumberExpression] 验证是否是数字格式 可以不填写,可以为任意数字

使用方法

* 组合使用演示
* [DisplayName("姓名")] 名称
*
[NotNullExpression] 不能为空
* [MaxWordsExpression(50)]
最多50个字符,25个汉字
* [IsCharExpression]
只能由数字,字母,中划线,下划线组成(一般用于验证ID)
* [NotEqualExpression("admin")]
不能包含有admin字符串
* public string Id { get; set; }
*
*
数字判断演示
* [IsNumberExpression] 可以不填写,填写判断是否是数字
* [DisplayName("代号")]

* public int? age { get; set; }
* 非空字断使用
*
//[Required(ErrorMessageResourceType = typeof(ErrorRs), ErrorMessageResourceName
= "IsNumberExpression")]
* 或//[Required(ErrorMessage="必须填写这个字段")]
来覆盖本地化 如public int age; int?为可空字端

摘一段代码解释一下吧 比如这个[NotNullExpression] 方法


 public class NotNullExpressionAttribute : ValidationAttribute, IClientValidatable
{
static string DispalyName = "";
public NotNullExpressionAttribute()
: base("{0}必须填写")
{
}
public override string FormatErrorMessage(string name)
{
return String.Format(name, DispalyName);
}

public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
string valueAsString = value.ToString();
bool result = !string.IsNullOrEmpty(valueAsString);
return result;

}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
DispalyName = metadata.DisplayName;
return new[]{
new ModelClientValidationRequiredRule(FormatErrorMessage("{0}必须填写"))
};
}
}

校验的方法          IsValid

客户端的验证规则 GetClientValidationRules

封装的错误信息    : base("{0}必须填写")  0代表的是displayName

其他方法都是类似的做法,大家可以根据自己的需要扩展验证。

我们来看看在实际项目中的应用吧!!


//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由T4模板自动生成
// 生成时间 2013-03-12 16:05:27 by App
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace App.Models.Sys
{
[DataContract]
public class SysSampleModel
{
[Display(Name = "ID")]
public string Id { get; set; }

[NotNullExpression]
[Display(Name = "名称")]
public string Name { get; set; }

[Display(Name = "年龄")]
[Range(0,10000)]
public int? Age { get; set; }

[Display(Name = "生日")]
public DateTime? Bir { get; set; }

[MaxLength(5)]
[Display(Name = "照片")]
[Required]
public string Photo { get; set; }
[MinLength(5)]
[Display(Name = "简介")]
public string Note { get; set; }

[DateExpressionAttribute]
[Display(Name = "创建时间")]
public DateTime? CreateTime { get; set; }

}
}

在model中使用了[NotNullExpression] 与[DateExpressionAttribute]日期验证

打开我们的代码生成器生成SysSample的Create视图,前提你已经创建自定义验证的类和在Create引入验证规则。

之前有关于系列的朋友都有这个样例。如果没有关注的,你可以自己创建一个普通的。

代码生成器生成以下代码:

@model App.Models.Sys.SysSampleModel
@using App.Common;
@using App.Models.Sys;
@using App.Admin;
@{
ViewBag.Title = "创建";
Layout = "~/Views/Shared/_Index_LayoutEdit.cshtml";
List<permModel> perm = (List<permModel>)ViewBag.Perm;
if (perm == null)
{
perm = new List<permModel>();
}
}

<script type="text/javascript">
$(function () {
$("#btnSave").click(function () {
if ($("form").valid()) {
$.ajax({
url: "@Url.Action("Create")",
type: "Post",
data: $("form").serialize(),
dataType: "json",
success: function (data) {
if (data.type == 1) {
window.parent.frameReturnByMes(data.message);
window.parent.frameReturnByReload(true);
window.parent.frameReturnByClose()
}
else {
window.parent.frameReturnByMes(data.message);
}
}
});
}
return false;
});
$("#btnReturn").click(function () {
window.parent.frameReturnByClose();
});
});
</script>
<div class="mvctool bgb">
@Html.ToolButton("btnSave", "icon-save", "保存", perm, "Save", true)
@Html.ToolButton("btnReturn", "icon-return", "返回",false)
</div>
@using (Html.BeginForm())
{
<table class="fromEditTable setTextWidth300">
<tbody>
<tr>
<td style="width:100px; text-align:right;">
@Html.LabelFor(model => model.Id):
</td>
<td style="width:310px">
@Html.EditorFor(model => model.Id)
</td>
<td>@Html.ValidationMessageFor(model => model.Id)</td>
</tr>
<tr>
<td style="width:100px; text-align:right;">
@Html.LabelFor(model => model.Name):
</td>
<td style="width:310px">
@Html.EditorFor(model => model.Name)
</td>
<td>@Html.ValidationMessageFor(model => model.Name)</td>
</tr>
<tr>
<td style="width:100px; text-align:right;">
@Html.LabelFor(model => model.Age):
</td>
<td style="width:310px">
@Html.EditorFor(model => model.Age)
</td>
<td>@Html.ValidationMessageFor(model => model.Age)</td>
</tr>
<tr>
<td style="width:100px; text-align:right;">
@Html.LabelFor(model => model.Bir):
</td>
<td style="width:310px">
@Html.EditorFor(model => model.Bir)
</td>
<td>@Html.ValidationMessageFor(model => model.Bir)</td>
</tr>
<tr>
<td style="width:100px; text-align:right;">
@Html.LabelFor(model => model.Photo):
</td>
<td style="width:310px">
@Html.EditorFor(model => model.Photo)
</td>
<td>@Html.ValidationMessageFor(model => model.Photo)</td>
</tr>
<tr>
<td style="width:100px; text-align:right;">
@Html.LabelFor(model => model.Note):
</td>
<td style="width:310px">
@Html.EditorFor(model => model.Note)
</td>
<td>@Html.ValidationMessageFor(model => model.Note)</td>
</tr>
<tr>
<td style="width:100px; text-align:right;">
@Html.LabelFor(model => model.CreateTime):
</td>
<td style="width:310px">
@Html.EditorFor(model => model.CreateTime)
</td>
<td>@Html.ValidationMessageFor(model => model.CreateTime)</td>
</tr>
</tbody>
</table>
}

预览效果

前端如果判断和自动输出错误的关键代码在$("form").valid() 这里

后台的关键判断代码在if (model != null && ModelState.IsValid)

只有都为true时才通过双向验证,有力保证系统数据库的安全

总结:其实极其简单的演示,我们创建的MVC3项目中实例已经可以看出来,然而我们封装的验证有效的重用于项目之间

       
 如果你有过硬的正则表达式基础,
你完全可以写出更多符合系统的表单验证

       
 这里我只是共享我写的一个验证类,可以直接使用与项目中,其他特性还待园友自行摸索了。

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(33)-数据验证共享

时间: 2024-12-09 11:14:33

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(33)-数据验证共享的相关文章

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(35)-文章发布系统②-构建项目

注:阅读本文,需要阅读本系列的之前文章 代码生成器下载地址(文章开头处) 接下来我们建立数据库的表和各层的代码 我们只需要两张表,文章列表(MIS_Article)和类别表(MIS_Article_Category) USE [AppDB] GO /****** Object: Table [dbo].[MIS_Article] Script Date: 05/15/2014 17:33:15 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(36)-文章发布系统③-kindeditor使用

我相信目前国内富文本编辑器中KindEditor 属于前列,详细的中文帮助文档,简单的加载方式,可以定制的轻量级.都是系统的首选 很多文章教程有kindeditor的使用,但本文比较特别可能带有,上传文件的缩略图和水印的源码!这块也是比较复杂和备受关注的功能 一.下载编辑器 KindEditor 4.1.10 (2013-11-23) [1143KB] 官方最新版 或者: http://www.kindsoft.net/down.php 二.添加到项目 解压 kindeditor-x.x.x.z

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(38)-Easyui-accordion+tree漂亮的菜单导航

本节主要知识点是easyui 的手风琴加树结构做菜单导航 有园友抱怨原来菜单非常难看,但是基于原有树形无限级别的设计,没有办法只能已树形展示 先来看原来的效果 改变后的效果,当然我已经做好了,最后只放出代码供大家参考,其实网上也有这方面的资料,但是不是很好用,我还是自己写了 改变后的效果 手风琴一直都是比较漂亮和受欢迎的,但是基于树多级别来说,做起来就比较麻烦,所以我这里也用了手风琴加树的模式来做 注:上面的图标都是乱添加的,并不代表意思 进入正文: 首先必须下载一些图标.可以自行百度网页小图标

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(37)-文章发布系统④-百万级数据和千万级数据简单测试

我想测试EF在一百万条数据下的显示时间!这分数据应该有很多同学想要,看看EF的性能! 服务器 现在来向SQL2008R2插入1000000条数据吧 declare @i int; set @i=0; while @i<1000000 begin INSERT INTO [AppDB].[dbo].[MIS_Article] ([Id] ,[ChannelId] ,[CategoryId] ,[Title] ,[ImgUrl] ,[BodyContent] ,[Sort] ,[Click] ,[C

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(47)-工作流设计-补充

原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(47)-工作流设计-补充 系列目录 补充一下,有人要表单的代码,这个用代码生成器生成表Flow_Form表的Index代码就可以 加上几个按钮就可以了 <div class="mvctool"> <input id="txtQuery" type="text" class="searchText" /> @Ht

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(48)-工作流设计-起草新申请

原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(48)-工作流设计-起草新申请 系列目录 创建新表单之后,我们就可以起草申请了,申请按照严格的表单步骤和分支执行. 起草的同时,我们分解流转的规则中的审批人并保存,具体流程如下 接下来创建DrafContoller控制器,此控制器只有2个页面,一个Create(起草页面)Index(表单列表) 表单列表显示个人想法,我是根据分类直接获取其下表单,即Flow_Type下的Flow_Form public

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(41)-组织架构

原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(41)-组织架构 本节开始我们要实现工作流,此工作流可以和之前的所有章节脱离关系,也可以紧密合并. 我们当初设计的项目解决方案就是可伸缩可以拆离,可共享的项目解决方案.所以我们同时要添加App.Flow文件夹 工作流的开始之前,我们必须有一个组织架构,我们做成无限动态级别树,因为之前的模块管理也是无限级别的 知识点:Easyui TreeGrid用法,根据组织架构读取架构下所有用户(with...as.

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(39)-在线人数统计探讨

原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(39)-在线人数统计探讨 系列目录 基于web的网站在线统计一直处于不是很精准的状态!基本上没有一种方法可以确实的统计在线用户! Discuz!NT 在线用户功能算是做得比较好的!参考资料 他的原理大致是根据用户的操作间隔来确定用户是否在线,也可以理解为操作日志,当系统扫描的日志间隔太长将被理解为用户离线,所以要不断的更新操作表和操作表日益增长的烦恼,所以必须定时的清除操作表,当系统启动时要重置表数据!

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(42)-工作流设计01

原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(42)-工作流设计01 工作流在实际应用中还是比较广泛,网络中存在很多工作流的图形化插件,可以做到拉拽的工作流设计,非常简便,再配合第三方编辑器,可以直接生成表单,我没有刻意的浏览很多工作流的实际设计,我认为工作流只要有动态可修改的流转,有时可按角色,部门,上级或者职位流转即是比较好的正常工作流!这里只带给一个思路的简单工作流... 工作流其实有几种,也可以设计得很简单: 1.固定的工作流,很小的公司,

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(40)-精准在线人数统计实现-【过滤器+Cache】

原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(40)-精准在线人数统计实现-[过滤器+Cache] 系列目录 上次的探讨没有任何结果,我浏览了大量的文章和个别系统的参考!决定用Cache来做,这可能有点难以接受但是配合mvc过滤器来做效果非常好! 由于之前的过滤器我们用过了OnActionExecuting这个方法来判断权限 现在在方法被执行后我们用OnActionExecuted来监听用户的操作和刷新用户在线列表 首先下载http://files