我最初使用NerdDinner教程作为基本大纲在MVC 1.0中构建了我的网站。许多早期的设计决策都是简单的b / c“这就是NerdDinner如何做到的”从那时起,它已经真正成长并转变为2.0。
我的验证仍然按照NerdDinner的方式进行,并且非常小,所以虽然我已经阅读了其他方法,但从来没有任何理由改变它。
我最近添加了一些十进制类型的新字段。在发布时,用户尝试输入值“$ 3000”和“3,000”并得到基本的“无效”错误。我向他解释说他只能在场上输入数字。我进入了验证,并为该字段添加了更好的验证,以便将来可以获得更具描述性的信息。但是,字段的值将作为null传递给我的验证例程。如果输入了有效的小数,则将其传递给验证例程。我已经对我的日期字段进行了验证,并意识到他们正在发生同样的事情。我的所有其他验证都是字符串,验证是检查我不允许的字符之类的东西,并且效果很好。但是,在这些情况下,它实际上并没有检查数据库会发现无效的东西。
这是我的验证样本:
public IEnumerable<RuleViolation> GetRuleViolations()
{
if (String.IsNullOrEmpty(subcontract_no.Trim()))
yield return new RuleViolation("Subcontract Number is required", "subcontract_no");
if (db.subcontracts.Count(s => (s.subcontract_no == subcontract_no) && (s.subcontract_id != subcontract_id)) > 0)
yield return new RuleViolation("Subcontract Number already exists", "subcontract_no");
if (subcontract_no.Contains("/")) // quick fix, needs better validation
yield return new RuleViolation("Subcontract Number cannot contain /", "subcontract_no");
if (!isValidDate(expiration_date.ToString()))
yield return new RuleViolation("Expiration Date is not valid", "expiration_date");
if (!isValidDecimal(insurance_GLminreq.ToString()))
yield return new RuleViolation("Insurance GL Level must be a number", "insurance_GLminreq");
“isValidDate”和“isValidDecimal”例程正如我所期望的那样工作,问题是如果insurance_GLminreq的值不是小数,则它将被传递为null而不是“$ 3,000”或其他任何东西。他们看到“价值'$ 3,000'对insurance_GLminreq无效”,而不是用户看到“保险GL级别必须是数字”消息。我希望这条消息更具描述性,因此他们知道为什么它无效,而且我宁愿他们没有看到实际的字段名称,而是与该字段的标签相匹配的东西。
是否有一种相对快速的解决方法,不涉及重写验证的方式?该网站的这一部分只有3个用户,我已经向他们解释过只输入这个数字。我希望这能正常工作,但在这一点上,对于这个小问题,我不能花很多时间重做它来使用另一种验证方法。
答案 0 :(得分:0)
解决此问题的一种方法是更改MVC模型:制作expiration_date
和insurance_GLminreq
字符串。
如果您还没有这样做,则需要引入可转换为域模型的视图模型,因为您确实希望这些值为DateTime
和{{1更进一步。 (请参阅Steve Michelotti的ASP.NET MVC View Model Patterns,了解您的选择。)
答案 1 :(得分:0)
使用jquery验证插件快速绕过这个问题。 http://bassistance.de/jquery-plugins/jquery-plugin-validation/