Asp.net mvc 如何在MVC中从包含所有自定义验证以及验证错误的文件中进行自定义验证

Asp.net mvc 如何在MVC中从包含所有自定义验证以及验证错误的文件中进行自定义验证,asp.net-mvc,validation,asp.net-mvc-4,Asp.net Mvc,Validation,Asp.net Mvc 4,我是MVC4新手。在我的项目中,我有一个要求,就是要有一个特殊的文件,其中包含各种验证错误号和相应的验证错误消息。然后,我希望在模型中定义这些错误号,并在上定义此类验证错误。我希望我的视图从该文件中获取相应的错误消息,并在验证摘要中显示它 找到了使用[Remote]属性实现功能的方法。我就是这样做的 模型CUSTS.cs namespace MvcTest.Models { public partial class CUSTS { public Nullable&

我是MVC4新手。在我的项目中,我有一个要求,就是要有一个特殊的文件,其中包含各种验证错误号和相应的验证错误消息。然后,我希望在模型中定义这些错误号,并在上定义此类验证错误。我希望我的视图从该文件中获取相应的错误消息,并在验证摘要中显示它


找到了使用
[Remote]
属性实现功能的方法。我就是这样做的

模型CUSTS.cs

namespace MvcTest.Models
{
    public partial class CUSTS
    {
        public Nullable<double> Field1 { get; set; }
        [Remote("ValidateAmount", "Validation", AdditionalFields = "Field1, Field2")]
        [Display(Name = "BALANCE AMT")]
        public Nullable<double> Field2 { get; set; }
    }
}
namespace MvcTest.Models
namespace MvcTest.Models
{
公共部分类客户
{
公共可空字段1{get;set;}
[远程(“ValidateAmount”、“Validation”,AdditionalFields=“Field1,Field2”)]
[显示(名称=“余额金额”)]
公共可空字段2{get;set;}
}
}
控制器验证controller.cs

namespace MvcTest.Controllers
{
    public class ValidationController : Controller
    {
        Entities1 db = new Entities1();
        public static NameValueCollection messagesCol;
        public String errorField;
        public String errorMessage;

        public JsonResult ValidateAmount(CUSTS custs)
        {
            CUSTS cus = new CUSTS();

            if (custs.Field2< custs.Field1)
            {
                loadMessages();

                String[] errMsg = new String[1];
                errMsg = messagesCol.GetValues("OES0373");
                string st=errMsg[0] + ". \r\n The Balance amount is:" + custs.XWIDV0 + " & the Credit Limit is:" + custs.XWGIVA;
                return Json(st,JsonRequestBehavior.AllowGet);
                //return new ActionResult(errMsg[0] + ". \r\n The Balance amount is:" + custs.XWIDV0 + " & the Credit Limit is:" + custs.XWGIVA);
            }
            return Json(true, JsonRequestBehavior.AllowGet);
            //return ActionResult.Success;
        }

        public static void loadMessages()
        {
            StreamReader sr = new StreamReader(System.Web.HttpContext.Current.Server.MapPath("~\\Models\\messages_en.properties"));
            String fileContents = sr.ReadToEnd();

            String[] sepr = new string[] { "\r\n" };
            String[] lines = fileContents.Split(sepr, StringSplitOptions.RemoveEmptyEntries);

            messagesCol = new NameValueCollection();
            int numMessages = lines.Length;

            foreach (string line in lines)
            {
                int indx = line.IndexOf('=');

                if (indx != -1)
                {
                    messagesCol.Add(line.Substring(0, indx), line.Substring(indx + 1));
                }
            }

            sr.Close();
        }
    }
}
namespace MvcTest.Controllers
namespace MvcTest.Controllers
{
公共类ValidationController:控制器
{
Entities1 db=新的Entities1();
公共静态NameValueCollection messagesCol;
公共字符串错误字段;
公共字符串错误消息;
公共JsonResult ValidateAmount(CUSTS CUSTS)
{
CUSTS cus=新CUSTS();
if(客户字段2<客户字段1)
{
loadMessages();
字符串[]errMsg=新字符串[1];
errMsg=messagesCol.GetValues(“OES0373”);
字符串st=errMsg[0]+”\r\n余额为:“+custs.XWIDV0+”&信用额度为:“+custs.XWGIVA;
返回Json(st,JsonRequestBehavior.AllowGet);
//返回新的ActionResult(errMsg[0]+”\r\n余额为:“+custs.XWIDV0+”,信用额度为:“+custs.XWGIVA”);
}
返回Json(true,JsonRequestBehavior.AllowGet);
//返回操作结果。成功;
}
公共静态void loadMessages()
{
StreamReader sr=新的StreamReader(System.Web.HttpContext.Current.Server.MapPath(“~\\Models\\messages\u en.properties”);
String fileContents=sr.ReadToEnd();
字符串[]sepr=新字符串[]{“\r\n”};
String[]line=fileContents.Split(sepr,StringSplitOptions.removemptyEntries);
messagesCol=新名称值集合();
int numMessages=行。长度;
foreach(行中的字符串行)
{
int indx=line.IndexOf('=');
如果(indx!=-1)
{
messagesCol.Add(行子字符串(0,indx),行子字符串(indx+1));
}
}
高级关闭();
}
}
}
现在我想问两件事

  • 这种实现所需功能的方法是否正确。还可以做些什么
  • 我刚刚诊断出的另一个问题是,无论验证是否有效,视图中表单中的post方法都在执行

  • 我是这样做的:

    1) 在DataAnnotationsModelValidatorProvider的cusotm实现中重写GetValidators()。在这里,您可以阅读文件并决定将哪些验证器附加到正在查看的属性

    2) 编写自己的ValidationAttribute并重写IsValid()方法以实现所需的自定义规则。您还可以覆盖FormatErrorMessage,以任意方式格式化错误消息。通过在ValidationAttribute中实现IClientValidable,您甚至可以将它们传播到客户端

    3) 在Global.asax中的应用程序_Start()中使用注册提供程序

    ModelValidatorProviders.Providers.Add(new VProvider());
    
    DataAnnotationsModelValidatorProvider的自定义实现可以如下所示:

    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
         IEnumerable<ModelValidator> toRet = new Collection<ModelValidator>();
         string prop = metadata.PropertyName;
         //get the custom rules you want applied from database or file or any other storage 
         AddImplicitRequiredAttributeForValueTypes = false; //to remove implicit required from value types if you want to
         //Determine what attributes you want to apply to this property
         attributes = new List<Attribute>() { new MyCustomAttribute() };
         //Ask the base class to construct the list of validators to return to the caller
         return = base.GetValidators(metadata, context, attributes);
    }
    
    受保护的重写IEnumerable GetValidator(ModelMetadata元数据、ControllerContext上下文、IEnumerable属性)
    {
    IEnumerable toRet=新集合();
    string prop=metadata.PropertyName;
    //从数据库、文件或任何其他存储中获取要应用的自定义规则
    AddImplicitRequiredAttributeForValueTypes=false;//若要从值类型中删除隐式,则需要
    //确定要应用于此属性的属性
    attributes=new List(){new MyCustomAttribute()};
    //要求基类构造要返回给调用方的验证程序列表
    return=base.GetValidators(元数据、上下文、属性);
    }
    
    自定义属性的外观类似于:

    public class MyCustomAttribute:ValidationAttribute, IClientValidatable
    {
        public override bool IsValid(object value)
        {
            //perform whatever tests you want here and return true/false
        }
        public override string FormatErrorMessage(string name)
        {
            //do some formatting
        }
    
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var r = new ModelClientValidationRule
                        {
                           ErrorMessage = "Some error message",
                           ValidationType = "customType",
                        };
            r.ValidationParameters.Add(paramName,paramValue);
    
            yield return r;
        }
    
    }
    
    公共类MyCustomAttribute:ValidationAttribute,IClientValidable
    {
    公共覆盖布尔值有效(对象值)
    {
    //在此处执行您想要的任何测试,并返回true/false
    }
    公共重写字符串FormatErrorMessage(字符串名称)
    {
    //做一些格式化
    }
    公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
    {
    var r=新的ModelClientValidationRule
    {
    ErrorMessage=“一些错误消息”,
    ValidationType=“customType”,
    };
    r、 ValidationParameters.Add(paramName,paramValue);
    收益率r;
    }
    }
    
    听起来,您需要使用带有错误消息的资源文件,然后使用内置属性参数进行本地化,例如:

    [Required(ErrorMessageResourceType=typeof(MyResourcesNameSpace.ResourcesFile),    
         ErrorMessageResourceName="FirstNameRequiredKey")]
    

    找到了一种通过使用 [远程] 属性我就是这样做的

    模型CUSTS.cs

    namespace MvcTest.Models
    {
        public partial class CUSTS
        {
            public Nullable<double> Field1 { get; set; }
            [Remote("ValidateAmount", "Validation", AdditionalFields = "Field1, Field2")]
            [Display(Name = "BALANCE AMT")]
            public Nullable<double> Field2 { get; set; }
        }
    }
    
    namespace MvcTest.Models
    
    {

    { 公共类ValidationController:控制器 { Entities1 db=新的Entities1(); 公共静态NameValueCollection messagesCol; 公共字符串错误字段; 公共字符串错误消息

        public JsonResult ValidateAmount(CUSTS custs)
        {
            CUSTS cus = new CUSTS();
    
            if (custs.Field2< custs.Field1)
            {
                loadMessages();
    
                String[] errMsg = new String[1];
                errMsg = messagesCol.GetValues("OES0373");
                string st=errMsg[0] + ". \r\n The Balance amount is:" + custs.XWIDV0 + " & the Credit Limit is:" + custs.XWGIVA;
                return Json(st,JsonRequestBehavior.AllowGet);
                //return new ActionResult(errMsg[0] + ". \r\n The Balance amount is:" + custs.XWIDV0 + " & the Credit Limit is:" + custs.XWGIVA);
            }
            return Json(true, JsonRequestBehavior.AllowGet);
            //return ActionResult.Success;
        }
    
    
        public static void loadMessages()
        {
            StreamReader sr =
                new StreamReader(System.Web.HttpContext.Current.Server.MapPath("~\\Models\\messages_en.properties"));
            String fileContents = sr.ReadToEnd();
    
            String[] sepr = new string[] { "\r\n" };
            String[] lines =
                fileContents.Split(sepr, StringSplitOptions.RemoveEmptyEntries);
    
            messagesCol = new NameValueCollection();
            int numMessages = lines.Length;
    
            foreach (string line in lines)
            {
                int indx = line.IndexOf('=');
    
                if (indx != -1)
                {
                    messagesCol.Add(line.Substring(0, indx), line.Substring(indx + 1));
                }
            }
    
            sr.Close();
        }
    }
    
    public JsonResult ValidateAmount(CUSTS-CUSTS)
    {
    CUSTS cus=新CUSTS();
    如果(客户)