2011-10-11 21 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