2013-10-21 42 views
0

我有一個名爲註冊視圖模型與EmailAddress的屬性設置是這樣的:的Web API驗證錯誤

[Required] 
[DuplicateEmailAddressAttribute(ErrorMessage = "This email address already exists")] 
public string EmailAddress { get; set; } 

和自定義驗證看起來是這樣的:

public class DuplicateEmailAddressAttribute : ValidationAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     PestControlContext _db = new PestControlContext(); 
     int hash = value.ToString().GetHashCode(); 

     if (value == null) 
     { 
      return true; 
     } 

     if (_db.Users.Where(x => x.EmailAddressHash == hash).Count() > 0) 
      return false; 
     else 
      return true; 
    } 
} 

我有問題如果用戶在註冊表單上留下了空白的電子郵件地址字段,應用程序就會拋出一個空引用異常錯誤(我認爲它正在數據庫中查找「」,並且找不到它)。我不明白的是爲什麼這不是由Required屬性處理 - 爲什麼它直接跳入自定義驗證器?

回答

0

Required屬性會導致錯誤被添加到模型狀態。儘管如此,它不會使執行短路。該框架繼續運行其他驗證器,原因很簡單,因爲全部是關於請求的錯誤需要一次性發送出去。理想情況下,您不希望服務說一開始是錯誤的,當用戶在糾正之後重新提交請求時,服務會返回並說出其他問題,等等。我想,這將是一個煩惱。

0

NullReferenceException被拋出,因爲在檢查null之前調用value.ToString()。當你只有檢查後需要的散列變量,您可以通過重新排序報表解決這個問題:

if (value == null) 
{ 
    return true; 
} 
int hash = value.ToString().GetHashCode(); 

此外,您還可以移動PestControlContext對空的檢查後,並使用using語句來處理它正常。
正如@Baldri指出的那樣,每個驗證器都可以添加錯誤消息,並且所有這些錯誤消息都可以運行,即使前一個驗證器已經表示數據無效。此外,我不會依賴於驗證是按照您在使用屬性標記屬性時指定的順序運行的(某些框架實施其自己的屬性排序機制來聲明順序是確定性的,例如優先級或先前屬性)。
因此,我建議重新排序自定義驗證程序中的代碼是最佳解決方案。