14

我的表單有默認幫助文本輸入,用於指導用戶輸入什麼(而不是使用標籤)。這使驗證非常棘手,因爲輸入值永遠不爲空。mvc3 validate input'not-equal-to'

如何擴展不顯眼的驗證來處理此問題?如果名稱輸入等於「請輸入您的姓名...」

我開始閱讀Brad Wilson's blog post驗證適配器,但我不確定這是否正確的路要走?我需要根據不同的字段對不同的默認值進行驗證。

謝謝

+0

或者模型設定,可以考慮使用[佔位符屬性(https://開頭開發商.mozilla.org/EN-US /文檔/網頁/ HTML /元/ input#attr-placeholder)顯示指令文本,如「請輸入您的姓名......」,作爲一種非常友好的用戶體驗,也是HTML5標準兼容的方式,以向用戶提供提示。 – KyleMit 2017-02-21 19:30:00

回答

2

是的,這是正確的路要走。你應該實現你自己的屬性並實現IClientValidatable

您也可以將所需的布爾值初始設置爲false作爲隱藏表單字段。當用戶更改文本框時,將其設置爲true。

-1

理想的解決方案是一個自定義屬性,您可以指定最小和最大長度以及MustNotContain =「請輸入您的名字......」。

+0

我真的不明白這個答案與這裏提出的問題有什麼關係,這是如何驗證視圖模型上的兩個屬性是不相等的。 – 2011-04-20 22:05:29

+1

我將問題閱讀爲 - 我如何知道名稱字段包含有效名稱,而不是默認值'請輸入您的名字'。這種性質的驗證可以用一個非常通用的屬性來執行,它可以在很多領域使用。 – Leons 2011-04-20 22:13:22

0

你可以讓你的ViewModel實現IValidatableObject,並在實現Validate方法時(從IValidatableObject)添加一些邏輯來檢查屬性的值,例如

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { 
     var results = new List<ValidationResult>(); 

     if (Name == "Please enter your name...") 
      results.Add(new ValidationResult("You must enter a name"); 

     ... 
     Enter other validation here 
     ...  

     return results; 
    } 

現在,當Model.IsValid被稱爲在你的控制器,邏輯,該位將運行並返回驗證錯誤是正常的。

31

下面是一個示例說明您如何着手實施自定義驗證屬性:

public class NotEqualAttribute : ValidationAttribute, IClientValidatable 
{ 
    public string OtherProperty { get; private set; } 
    public NotEqualAttribute(string otherProperty) 
    { 
     OtherProperty = otherProperty; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var property = validationContext.ObjectType.GetProperty(OtherProperty); 
     if (property == null) 
     { 
      return new ValidationResult(
       string.Format(
        CultureInfo.CurrentCulture, 
        "{0} is unknown property", 
        OtherProperty 
       ) 
      ); 
     } 
     var otherValue = property.GetValue(validationContext.ObjectInstance, null); 
     if (object.Equals(value, otherValue)) 
     { 
      return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
     } 
     return null; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = ErrorMessage, 
      ValidationType = "notequalto", 
     }; 
     rule.ValidationParameters["other"] = OtherProperty; 
     yield return rule; 
    } 
} 

,然後在模型上:

public class MyViewModel 
{ 
    public string Prop1 { get; set; } 

    [NotEqual("Prop1", ErrorMessage = "should be different than Prop1")] 
    public string Prop2 { get; set; } 
} 

控制器:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel 
     { 
      Prop1 = "foo", 
      Prop2 = "foo" 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

和視圖:

@model MyViewModel 

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> 
<script type="text/javascript"> 
    jQuery.validator.unobtrusive.adapters.add(
     'notequalto', ['other'], function (options) { 
      options.rules['notEqualTo'] = '#' + options.params.other; 
      if (options.message) { 
       options.messages['notEqualTo'] = options.message; 
      } 
    }); 

    jQuery.validator.addMethod('notEqualTo', function(value, element, param) { 
     return this.optional(element) || value != $(param).val(); 
    }, ''); 
</script> 

@using (Html.BeginForm()) 
{ 
    <div> 
     @Html.LabelFor(x => x.Prop1) 
     @Html.EditorFor(x => x.Prop1) 
     @Html.ValidationMessageFor(x => x.Prop1) 
    </div> 
    <div> 
     @Html.LabelFor(x => x.Prop2) 
     @Html.EditorFor(x => x.Prop2) 
     @Html.ValidationMessageFor(x => x.Prop2) 
    </div> 
    <input type="submit" value="OK" /> 
} 
+1

非常好的答案+1 – tgriffiths 2012-08-14 14:51:09

+0

工程就像一個魅力,但你提供的解決方案不能使用ErrorMessageResourceType和ErrorMessageResourceName。你可以使用像這樣的東西:errorMessage = new ResourceManager(ErrorMessageResourceType).GetString(ErrorMessageResourceName); – Rookian 2013-02-06 15:53:49

+0

偉大的答案,非常有助於讓我在正確的軌道上做一些自定義驗證。 – Etch 2013-11-02 02:55:39

0

過了一小會兒,因爲你的問題被問,但使用this library,如果你還是喜歡數據註解,這個問題就可以迎刃而解:

[Required] 
[AssertThat("FieldA != 'some text'")] 
public string FieldA { get; set; } 

以上,字段值與一些相比前定義的文本。或者,您可以比較字段值彼此:

[AssertThat("FieldA != FieldB")] 

...當被比較不要緊字符串的情況:

[AssertThat("CompareOrdinalIgnoreCase(FieldA, FieldB) != 0")] 
0

爲了提高@Darin季米特洛夫回答的一點點,如果你想使用ErrorMessageResourceName and ErrorMessageResourceType資源添加郵件,只需添加這到到錯誤消息ErrorMessage = ErrorMessage ?? ErrorMessageString

的ErrorMessageString將尋找錯誤信息的本地化版本,您使用這些參數(ErrorMessageResourceName和ErrorMessageResourceType)