2014-10-30 78 views
1

我想使用自定義驗證,但被忽略。我沒有得到任何錯誤或任何東西。它什麼都不做。我究竟做錯了什麼?謝謝你的閱讀。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("/.,[email protected]#$%")] // <<<====== 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; 
     } 
    } 
} 
+0

你調試了你的驗證屬性嗎?你有沒有考慮使用正則表達式來防止某些字符被輸入? – benjrb 2014-10-30 16:03:02

+0

對不起。當我運行程序時,我得到這個錯誤:「無法獲得屬性值'不顯眼':對象爲空或未定義」。我搜索了一下,並嘗試了一些建議,但沒有運氣。 – ceci 2014-10-30 16:38:27

+0

去哪兒發生這個錯誤? – benjrb 2014-10-30 16:41:47

回答

0

我有完全相同的問題,並使用相同的代碼。我只關閉我的應用程序並重新啓動。它爲我工作。試試這個

+0

在評論中,它看起來像原來的提問者已經嘗試了這一點。 – kaz 2015-05-21 14:02:05

0

你的代碼通常看起來正確。然而,這將驗證在服務器端,您通常擁有它的方式以及它是否正常工作。此外,我不確定爲什麼某些示例僅覆蓋方法的ValidationResult版本,而其他示例僅覆蓋了變體。

如果您想要客戶端驗證,您需要實現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 
     ); 
    } 
} 
1

請檢查操作方法在你的控制器 - 確保模型類型所使用的參數,例如

public ActionResult Foo(ModelMetaData model)