ASP.NET MVC 4自定义验证无效

时间:2014-10-30 15:55:18

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

我正在尝试使用自定义验证,但它已被忽略。我没有任何错误或任何错误。它什么都不做。我究竟做错了什么?谢谢你的阅读。

---的 ModelMetadata.cs ----

using System.ComponentModel.DataAnnotations; 
using myproject.Common;

namespace myproject.Models
{
    [MetadataType(typeof(ModelMetaData))]
    public partial class Reference
    { 
    }

    public class ModelMetaData { 
        [Required]
        [Display(Name = "Full Name *")]
        [ExcludeCharacters("/.,!@#$%")] // <<<====== This is being ignored. 
        public string Name { get; set; } 
    }
}

- Create.cshtml ----

<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script> 
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

@using (Html.BeginForm()){
@Html.AntiForgeryToken()
@Html.ValidationSummary(true) 

    <div class="editor-field">
        @Html.EditorFor(model => model.Name) // <<<====== field 
        @Html.ValidationMessageFor(model => model.Name)
    </div>

- ExcludeCharacters.cs ---

namespace myproject.Common
{
    public class ExcludeCharacters : ValidationAttribute 
    {
        private readonly string _chars;

        public ExcludeCharacters(string chars) : base("{0} contains invalid characters")
        {
            _chars = chars;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                for (int i = 0; i < _chars.Length; i++)
                {
                    var valueAsString = value.ToString();
                    if (valueAsString.Contains(_chars[i].ToString()))
                    {
                        var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                        return new ValidationResult(errorMessage);
                    }
                }
            }
            return ValidationResult.Success;  
        }  
    } 
}

3 个答案:

答案 0 :(得分:1)

请检查控制器中的操作方法 - 确保参数使用模型类型,例如

public ActionResult Foo(ModelMetaData model)

答案 1 :(得分:0)

我有完全相同的问题,并且也使用相同的代码。我只是关闭我的应用程序并重新启动。它对我有用。试试这个

答案 2 :(得分:0)

您的代码通常看起来是正确的。但是,这将在服务器端验证您通常拥有它的方式以及它是否正常工作。此外,我不确定为什么某些示例仅覆盖 IsValid 方法的 ValidationResult 版本,而其他示例仅覆盖 bool < / strong> variant。

如果您需要客户端验证,则需要实现IClientValidatable,并在客户端注册适配器。

以下是我能够开展工作的一些代码。我需要在验证包含后包含我的js文件,因为我使用包含客户端库的DevExpress,我也需要在它们之后运行它。

您也(为了客户端工作),想要使用EditorFor或TextBoxFor类型方法来添加字段,但这似乎是您已经在做的事情。但是,请检查您的HTML并查找所添加的验证属性。

我已经用我的MM / dd / yyyy字段对此进行了测试。

<强> RangeSmallDateTime.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace YourNamespaceHere.Filters
{
    public class RangeSmallDateTime : ValidationAttribute, IClientValidatable
    {
        private static DateTime _minValue = new DateTime(1900, 1, 1);
        private static DateTime _maxValue = new DateTime(2079, 6, 6);

        public override bool IsValid(object value)
        {
            DateTime? dateValue = value as DateTime?;

            if (!dateValue.HasValue)
            {
                return true;
            }
            else 
            {
                return (dateValue.Value >= _minValue && dateValue.Value <= _maxValue);
            }
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format("The '{0}' field has an invalid value.", name);
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule rule = new ModelClientValidationRule();
            rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
            rule.ValidationType = "rangesdt";
            yield return rule;
        }


    }
}

<强> SmallDateTimeValidator.js:

$.validator.unobtrusive.adapters.addBool("rangesdt");

$.validator.addMethod("rangesdt", function (value, element) {
    if (value == null) {
        return true;
    }
    var date = new Date(value);  // MM/dd/yyyy

    var minDate = new Date(1900,1,1);
    var maxDate = new Date(2079, 6, 6);

    if (!dates.inRange(date, minDate, maxDate))
        return false;

    return true;
});

// Source: http://stackoverflow.com/questions/497790
var dates = {
    convert: function (d) {
        // Converts the date in d to a date-object. The input can be:
        //   a date object: returned without modification
        //  an array      : Interpreted as [year,month,day]. NOTE: month is 0-11.
        //   a number     : Interpreted as number of milliseconds
        //                  since 1 Jan 1970 (a timestamp) 
        //   a string     : Any format supported by the javascript engine, like
        //                  "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
        //  an object     : Interpreted as an object with year, month and date
        //                  attributes.  **NOTE** month is 0-11.
        return (
            d.constructor === Date ? d :
            d.constructor === Array ? new Date(d[0], d[1], d[2]) :
            d.constructor === Number ? new Date(d) :
            d.constructor === String ? new Date(d) :
            typeof d === "object" ? new Date(d.year, d.month, d.date) :
            NaN
        );
    },
    compare: function (a, b) {
        // Compare two dates (could be of any type supported by the convert
        // function above) and returns:
        //  -1 : if a < b
        //   0 : if a = b
        //   1 : if a > b
        // NaN : if a or b is an illegal date
        // NOTE: The code inside isFinite does an assignment (=).
        return (
            isFinite(a = this.convert(a).valueOf()) &&
            isFinite(b = this.convert(b).valueOf()) ?
            (a > b) - (a < b) :
            NaN
        );
    },
    inRange: function (d, start, end) {
        // Checks if date in d is between dates in start and end.
        // Returns a boolean or NaN:
        //    true  : if d is between start and end (inclusive)
        //    false : if d is before start or after end
        //    NaN   : if one or more of the dates is illegal.
        // NOTE: The code inside isFinite does an assignment (=).
        return (
             isFinite(d = this.convert(d).valueOf()) &&
             isFinite(start = this.convert(start).valueOf()) &&
             isFinite(end = this.convert(end).valueOf()) ?
             start <= d && d <= end :
             NaN
         );
    }
}