配合ModelState使用,关于使用方法,参考微软文档
自定义Data Annotations只需要继承ValidationAttribute,并且重写IsValid方法。
示例:
// ===================================================================
// ModelState自定义注解
// 多个字段分组判断,全部不允许为空或至少有一个不为空
//====================================================================
// CreateTime:2019-04-24
// Author:liucx
// ===================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OF.Component.Model
{
///
/// 多个属性字段分组不为空判断 传入参数逗号间隔
/// [GroupEmpty("p1,p2,p3",false,ErrorMessage="p1p2p3三个参数中至少有一个非空")]
///
public class GroupEmptyAttribute : ValidationAttribute
{
private readonly string _groupFields;
private readonly bool _notNullableAll;
///
/// 构造函数
///
/// 属性名,多个属性名逗号隔开
/// true全部不允许为空。 false只要存在不为空的属性即可
public GroupEmptyAttribute(string groupFields, bool notNullableAll)
{
_groupFields = groupFields;
_notNullableAll = notNullableAll;
}
///
/// 构造函数,默认至少1个非空
///
/// 属性名,多个属性名逗号隔开
public GroupEmptyAttribute(string groupFields)
{
_groupFields = groupFields;
_notNullableAll = false;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var validateResult = false;
var obj = validationContext.ObjectInstance;
Type Ts = obj.GetType();
var fields = _groupFields.Split(',');
if (fields.Count() > 0)
{
for (var i = 0; i < fields.Count(); i++)
{
var filedName = Convert.ToString(fields[i]);
if (string.IsNullOrEmpty(filedName)) continue;
//value
string filedValue = Convert.ToString(Ts.GetProperty(filedName).GetValue(obj, null));
//_notNullableAll=true,任意一个为空直接验证挂掉跳出循环
if (_notNullableAll && string.IsNullOrWhiteSpace(filedValue))
{
validateResult = false;
break;
}
//_notNullableAll=false,只要有一个不为空就可以过验证
if (!_notNullableAll && !string.IsNullOrWhiteSpace(filedValue))
{
validateResult = true;
break;
}
}
}
//success
if (validateResult)
return ValidationResult.Success;
else
{
//fail
if (string.IsNullOrEmpty(ErrorMessage) && _notNullableAll)
return new ValidationResult($"{_groupFields}字段全部不允许为空值");
else if (string.IsNullOrEmpty(ErrorMessage) && !_notNullableAll)
return new ValidationResult($"{_groupFields}字段中至少要有一个不为空的值");
else
return new ValidationResult(ErrorMessage);
}
}
}
///
/// 组内数据同步判断,同时为空或同时不为空通过验证
///
public class GroupEmptySyncAttribute : ValidationAttribute
{
private readonly string _groupFields;
public GroupEmptySyncAttribute(string groupFields)
{
_groupFields = groupFields;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var validateResult = true;
var obj = validationContext.ObjectInstance;
Type Ts = obj.GetType();
var fields = _groupFields.Split(',');
if (fields.Count() > 0)
{
bool firstValueIsEmpty = true;//第一个值是否为空
for (var i = 0; i < fields.Count(); i++)
{
var filedName = Convert.ToString(fields[i]);
if (string.IsNullOrEmpty(filedName)) continue;
//value
string filedValue = Convert.ToString(Ts.GetProperty(filedName).GetValue(obj, null));
//第一个值记录是否为空
if (i == 0 && string.IsNullOrWhiteSpace(filedValue))
firstValueIsEmpty = true;
if (i == 0 && !string.IsNullOrWhiteSpace(filedValue))
firstValueIsEmpty = false;
//后续值判断是否和第一个值符合,不符合直接结束验证
if (i > 0)
{
if (string.IsNullOrWhiteSpace(filedValue) != firstValueIsEmpty)
{
validateResult = false;
break;
}
}
}
}
//success
if (validateResult)
return ValidationResult.Success;
else
{
//fail
if (string.IsNullOrEmpty(ErrorMessage))
return new ValidationResult($"{_groupFields}字段是否为空不一致(必须同时为空或同时不为空)");
else
return new ValidationResult(ErrorMessage);
}
}
}
///
/// 判断时间格式是否对应,时间格式一致通过验证
///
public class DateFormatValidAttribute : ValidationAttribute
{
private readonly string _formatStr;
public DateFormatValidAttribute(string formatStr)
{
_formatStr = formatStr;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var validateResult = false;
try
{
//转成要求的格式后 再和传入的值对比
var formatValue = Convert.ToDateTime((string)value).ToString(_formatStr);
if ((string)value == formatValue)
validateResult = true;
else
validateResult = false;
//success
if (validateResult)
return ValidationResult.Success;
else
{
//fail
if (string.IsNullOrEmpty(ErrorMessage))
return new ValidationResult($"时间格式不符合{_formatStr}格式");
else
return new ValidationResult(ErrorMessage);
}
}
catch (Exception ex)
{
if (string.IsNullOrEmpty(ErrorMessage))
return new ValidationResult($"时间格式不符合{_formatStr}格式");
else
return new ValidationResult(ErrorMessage);
}
}
}
}
使用:
测试结果: