2011-11-24 63 views
0

我有一個EF Code First模型,我正在通過MVC頁面進行編輯,其中一個特定的字段總是通過[Required]數據註釋返回false。如果我在驗證之前很難設置一個值,它仍然會失敗。必需的驗證器總是返回false

這是一個用戶對象,如果我使用用戶名或電子郵件地址作爲'用戶名'屬性,我可以對其進行配置。

型號:

public class User { 
    [DisplayName("User Id")] 
    public int Id { get; set; } 

    [Required(ErrorMessage="Username is required")] 
    public string Username { get; set; } 

    [UIHint("EmailAddress")] 
    [Required(ErrorMessage = "Email is required")] 
    [EmailAddress] 
    public string Email { get; set; } 
} 

在我看來,我只是繪製Username編輯器,如果它需要:

@if (@ViewBag.LoginMethod == "username") { 
    @Html.LabelFor(m => m.Username) 
    @Html.TextBoxFor(m => m.Username, new { autocomplete = "off" }) 
    @Html.ValidationMessageFor(m => m.Username) 
} 

@Html.LabelFor(m => m.Email) 
@Html.TextBoxFor(m => m.Email, new { autocomplete = "off" }) 
@Html.ValidationMessageFor(m => m.Email) 

我的控制器:

[HttpPost] 
public ActionResult Create(UserModel viewModel) { 
     ViewBag.LoginMethod = this.loginMethod.ToString(); 

     var user = new User(); 
     if (this.loginMethod == LoginMethods.Username) 
      user.Username = viewModel.User.Username; 
     else 
      user.Username = viewModel.User.Email; 

     user.Email = viewModel.User.Email; 
     user.FirstName = viewModel.User.FirstName; 
     user.LastName = viewModel.User.LastName; 

     user.Username = "TEST"; 
     if (TryValidateModel(user) == false) { 
      this.FlashError("Validation Errors!"); 
      return View(viewModel); 
     } 

     throw new Exception("here"); 
} 

,你可以請參閱我將根據登錄方法設置User.Username屬性。爲了測試,我將它設置爲「測試」,就在驗證之前。 用戶名必填驗證返回false,最後回到我的視圖。我從來沒有得到例外。

我已經設法使它正常工作,通過在頁面上呈現用戶名編輯器,無論如何。由於我啓用了客戶端驗證,因此我無法提交表單而沒有輸入值,並且它可以工作 - 即使用戶名值在驗證後仍然是「測試」。

我開始認爲TryValidateModel不是正確的功能。使用ModelState.IsValid會得到相同的結果 - 錯誤的必需失敗。

回答

0

首先,我認爲您現在可以使用EditFor,避免每次都創建三個控件(標籤,文本框,驗證器)。

另一件讓我覺得奇怪的事情是,你的模型似乎是User(m.Email)類型,但是你的動作需要一個UserModel(它包含一個用戶)。我不確定爲什麼你的代碼仍然有效。通常,您可以直接將用戶作爲參數(因此您不必手動複製值)。

如果ModelState.IsValid不起作用,這是正常的。如果您的模型屬於User類型,則將嘗試驗證所有POSTED屬性,而不管它們是否在視圖中。另一方面,TryValidateModel應該在你的場景中工作。看起來有一個額外的安全功能,它認爲空的沒有編輯控制的屬性。 解決方法是自己創建用戶對象的自定義模型聯編程序(並不難,您繼承IModelBinder,重寫BindModel並調用基本方法)。之後,如果UserName爲空,則添加「TEST」或正確的值。當然,你不能把它留空)。在Asp.net MVC中搜索自定義模型綁定器。

我希望有幫助!

+0

我有兩個模型在viewmodel,用戶和一個成員對象,它有認證信息(密碼,登錄時間戳等)。我認爲你對「增加的安全功能」是正確的。在這一點上,我正在創建一個新的User對象,並手工從FormCollection中填充它。 – mattdwen

+0

我很抱歉,延遲響應(我仍然習慣於接口)。它是如何去的?如果您沿着手動人口路線走下去了,如果您創建ModelBinder,則可能更有趣。通過這種方式,您可以在發送用戶對象的任何地方重複使用此代碼。另外,ModelBinder有一些有趣的受保護的方法可以幫助手動填充。 –