0

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

找到了一种通过使用[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 方法正在执行,而不管验证是否有效。
4

3 回答 3

1

以下是我的做法:

1) 在 DataAnnotationsModelValidatorProvider 的自定义实现中覆盖 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;
    }

}
于 2012-09-07T06:49:44.657 回答
0

听上去像是需要使用带有错误消息的资源文件,然后使用内置的属性参数进行本地化,例如:

[Required(ErrorMessageResourceType=typeof(MyResourcesNameSpace.ResourcesFile),    
     ErrorMessageResourceName="FirstNameRequiredKey")]
于 2012-09-07T06:53:04.953 回答
0

找到了一种通过使用 [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

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

    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方法正在执行,而不管验证是否有效。

于 2012-09-11T04:41:28.993 回答