[attributeusage(attributetargets.property | attributetargets.field | attributetargets.parameter)] public class minfieldattribute : basecompareattribute { public string minvaluefield { get; set; } private string mindisplayname { get; set; } public minfieldattribute(type operandtype, string minvaluefield,string mindisplayname) : base(operandtype, minvaluefield, () => localizationextensions.t("rundong.infrastructure.minfieldattribute.errormsg", "{0}不能小于{1}")) { minvaluefield = minvaluefield; mindisplayname = mindisplayname; } protected override validationresult isvalid(object value, validationcontext validationcontext) { var minpropertyinfo = validationcontext.objecttype.getproperty(minvaluefield); if (minpropertyinfo == null) { return new validationresult(string.format(cultureinfo.currentculture, localizationextensions.t("rundong.infrastructure.minfieldattribute.notexist", "{0}不存在"), minvaluefield)); } var minpropertyvalue = minpropertyinfo.getvalue(validationcontext.objectinstance, null); var comparevalue = (icomparable) value; if (value!=null&& comparevalue.compareto(minpropertyvalue)<0) { if (mindisplayname == null) { mindisplayname = modelmetadataproviders.current.getmetadataforproperty( () => validationcontext.objectinstance, validationcontext.objecttype, minvaluefield).getdisplayname(); } return new validationresult(formaterrormessage(validationcontext.displayname)); } return null; } public override string formaterrormessage(string name) { return string.format(errormessagestring, name, mindisplayname??minvaluefield); } }
public class minfieldvalidationmetadata<tvaluetype> : modelvalidationmetadata where tvaluetype : struct { public string minvaluefield { get; set; } protected override modelvalidator createvalidatorcore(extendedmodelmetadata modelmetadata, controllercontext context) { var type = typeof(tvaluetype?).getunderlyingtype(); var minmodelmetadata= modelmetadata.properties.firstordefault(a => a.propertyname == minvaluefield); var mindisplayname = minmodelmetadata!=null ? minmodelmetadata.getdisplayname() : modelmetadataproviders.current.getmetadataforproperty(() => null, modelmetadata.containertype, minvaluefield).getdisplayname(); var attribute = new minfieldattribute(type, minvaluefield, mindisplayname); return new basecompareattributeadapter(modelmetadata, context, attribute){minvaluefield = minvaluefield }; } }
通过重写isvalid方向添加自定义验证,minvaluefield为需要比较的字段名,mindisplayname是显示的名字。basecompareattribute记录的构造函数第三个参数为重写formaterrormessage函数,以及提供比较值的类型转换
具体是参考微软两个字段比较是否相同https://github.com/aspnet/aspnetwebstack/blob/master/src/system.web.mvc/compareattribute.cs
黄山市民网:https://www.huangshanshimin.com/