2011-10-11 41 views
0

我試圖添加一個經典的接受條款和條件複選框在MVC應用程序的頁面上登錄。ASP.NET MVC 3複選框保留以前的值,儘管模型值

如果用戶接受條款和條件,但由於某些其他原因(錯誤密碼等)而未能登錄,那麼我想要選中Accept T & Cs複選框,以便用戶被強制接受T & Cs對每次登錄嘗試。

問題是,使用Html.CheckboxFor(),回發後複選框保留其先前的值,儘管綁定的模型屬性的值。

下面是代碼,分解爲要點。如果您運行此代碼,請選中該複選框,然後單擊該按鈕,即使綁定的模型屬性爲false,您也會返回到表單,並且該複選框仍處於選中狀態。

模型:

namespace Namespace.Web.ViewModels.Account 
{ 
    public class LogOnInputViewModel 
    { 
     [IsTrue("You must agree to the Terms and Conditions.")] 
     public bool AcceptTermsAndConditions { get; set; } 
    } 
} 

驗證屬性:

public class IsTrueAttribute : ValidationAttribute 
{ 
    public IsTrueAttribute(string errorMessage) : base(errorMessage) 
    { 
    } 

    public override bool IsValid(object value) 
    { 
     if (value == null) return false; 
     if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties."); 
     return (bool)value; 
    } 
} 

觀:

@model Namespace.Web.ViewModels.Account.LogOnInputViewModel 

@using (Html.BeginForm()) { 
    @Html.CheckBoxFor(x => x.AcceptTermsAndConditions) 
    <input type="submit" value="Log On" /> 
} 

控制器:

[HttpGet] 
    public ActionResult LogOn(string returnUrl) 
    { 
     return View(new LogOnInputViewModel { AcceptTermsAndConditions = false }); 
    } 

    [HttpPost] 
    public ActionResult LogOn(LogOnInputViewModel input) 
    { 
     return View(new LogOnInputViewModel { AcceptTermsAndConditions = false }); 
    } 

我看到了建議on asp.net將@checked屬性添加到CheckboxFor。我試過這個,製作視圖

@model Namespace.Web.ViewModels.Account.LogOnInputViewModel 

@using (Html.BeginForm()) { 
    @Html.CheckBoxFor(x => x.AcceptTermsAndConditions, new { @checked = Model.AcceptTermsAndConditions }) 
    <input type="submit" value="Log On" /> 
} 

而且我看到了相同的行爲。

感謝您的任何幫助/見解!

編輯:雖然我想重寫回發值,我想如果AcceptTermsAndConditions的驗證失敗時保留消息(上有要求它是真實的AcceptTermsAndConditions驗證屬性),所以我不能使用ModelState.Remove("AcceptTermsAndConditions")這是@counsellorben給我的答案。我已經編輯了上面的代碼,以包含驗證屬性 - 道歉到@counsellorben最初不明顯。

回答

3

您需要清除模型狀態AcceptTermsAndConditions。通過設計,CheckBoxFor和其他數據綁定幫助程序首先與ModelState綁定,如果沒有該元素的ModelState,則與模型綁定。以下內容添加到您的POST操作:

ModelState.Remove("AcceptTermsAndConditions"); 
+0

道歉,我已經錯過了AcceptTermsAndConditions使用驗證,打破'ModelState.Remove( 「AcceptTermsAndConditions」)'。有人可能會說我在這裏濫用驗證屬性,因爲有時候我想用AcceptTermsAndConditions'false'返回沒有驗證消息的表單(因爲他們用AcceptTermsAndConditions'true'回發)。也許我應該遠離驗證屬性,並且只需在Post方法中手動檢查AcceptTermsAndConditions?雖然我希望在我有更多時間的情況下將驗證屬性擴展爲IClientValidatable。 – SamStephens