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

时间:2012-09-07 06:41:30

标签: asp.net-mvc validation asp.net-mvc-4

我是MVC 4的新手。在我的项目中,我有一个要求是要有一个包含各种验证错误no的特殊文件及其相应的验证错误消息。然后我希望在模型中定义这些错误否,并且这样的验证错误我希望我的视图从该文件中获取相应的错误消息并将其显示在验证摘要中。

找到一种使用[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; }
    }
}

控制器ValidationController.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();
        }
    }
}

现在我想问两件事

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

3 个答案:

答案 0 :(得分:1)

我是这样做的:

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

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

3)使用

在Global.asax中的Application_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);
}

自定义属性看起来像:

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;
    }

}

答案 1 :(得分:0)

听起来是您需要将资源文件与错误消息一起使用,然后使用内置属性参数进行本地化,例如:

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

答案 2 :(得分:0)

找到一种通过使用来实现功能的方法     [远程] 属性。这就是我做到的。

模型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; }
}

}

控制器ValidationController.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();
    }
}

}

现在我想问两件事 1.这种实现所需功能的方法是否正确。还有什么可以做的。   2.我刚刚诊断出的另一个问题是视图中的post方法正在执行,无论验证是否有效。