我有一个视图,其中包含我的网站条款和条件的单选按钮列表.
例如
Yes
@Html.RadioButtonFor(model => model.TermsAndConditions, "True")
No
@Html.RadioButtonFor(model => model.TermsAndConditions, "False",
new { Checked = "checked" })
</div>
@Html.ValidationStyledMessageFor(model => model.TermsAndConditions)
Run Code Online (Sandbox Code Playgroud)
如果用户完成表单没有任何错误,一切正常,但如果我进行服务器端验证并刷新页面,则会丢失用户为单选按钮做出的选择,并且选定的无线电将返回到默认的假字段.
我是如何绑定radiobutton所以如果用户选择为true,即使在服务器端验证之后,该值仍然保持不变?
任何建议都会很棒!
Gla*_*zed 95
简而言之,您需要做三件事:
new { Checked = "checked" }
从第二个单选按钮中删除.这个硬编码的检查值将覆盖所有魔法.true
和false
作为单选按钮的值而不是"True"
和"False"
.这是因为您的属性属于类型bool
.严格地说,你恰巧为true
和选择了正确的字符串表示false
,但是RadioButtonFor方法的value参数是类型object
.最好传递您想要比较的实际类型,而不是自己将其转换为字符串.更多关于此的信息.以下是深入的内容:
该框架希望自动为您完成所有这些操作,但是您错误地执行了前两项操作,这使您必须与框架作斗争才能获得所需的行为.
RadioButtonFor方法调用.ToString()
您指定的属性的值,并将其与.ToString()
创建单选按钮时传入的值进行比较.如果它们相等,那么它在内部设置isChecked = true
并最终checked="checked"
在HTML中呈现.这就是它决定检查哪个单选按钮的方法.它只是将单选按钮的值与属性的值进行比较,并检查匹配的值.
您可以通过这种方式为几乎任何属性渲染单选按钮,它将神奇地工作.字符串,整数,甚至枚举类型都有效!任何具有ToString
返回唯一表示对象值的字符串的方法的对象都可以使用.您只需确保将单选按钮的值设置为您的属性可能实际具有的值.最简单的方法是传递值本身,而不是值的字符串表示.让框架为您将其转换为字符串.
(既然你发生在正确字符串表示通过true
和false
,然后将这些值将只要您修复两个实际工作的失误,但它仍然是明智的实际值,而不是他们的字符串传递.)
你的第一个真正的错误是硬编码Checked = "checked"
"No"单选按钮.这将覆盖框架尝试为您执行的操作,并导致始终检查此单选按钮.
显然,您希望预先选择"否"单选按钮,但您必须以与上述所有内容兼容的方式执行此操作.您需要为视图提供模型类的实例,其中TermsAndConditions设置为false,并让它"绑定"到单选按钮.通常,响应URL的初始GET请求的控制器操作根本不会向View提供模型类的实例.通常,你只是return View();
.但是,由于您希望选择默认值,因此必须为视图提供将TermsAndConditions设置为false的模型实例.
以下是一些说明所有这些的源代码:
您可能已经拥有的某种Account类.(你的View的型号):
public class Account
{
public bool TermsAndConditions { get; set; }
//other properties here.
}
Run Code Online (Sandbox Code Playgroud)
控制器中的一些方法:
//This handles the initial GET request.
public ActionResult CreateAccount()
{
//this default instance will be used to pre-populate the form, making the "No" radio button checked.
var account = new Account
{
TermsAndConditions = false
};
return View( account );
}
//This handles the POST request.
[HttpPost]
public ActionResult CreateAccount( Account account )
{
if ( account.TermsAndConditions )
{
//TODO: Other validation, and create the account.
return RedirectToAction( "Welcome" );
}
else
{
ModelState.AddModelError( "TermsAndConditionsAgreement", "You must agree to the Terms and Conditions." );
return View( account );
}
}
//Something to redirect to.
public ActionResult Welcome()
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
整个视图:
@model Account
@{
ViewBag.Title = "Create Account";
}
@using ( Html.BeginForm() )
{
<div>
<span>Do you agree to the Terms and Conditions?</span>
<br />
@Html.RadioButtonFor( model => model.TermsAndConditions, true, new { id = "TermsAndConditions_true" } )
<label for="TermsAndConditions_true">Yes</label>
<br />
@Html.RadioButtonFor( model => model.TermsAndConditions, false, new { id = "TermsAndConditions_false" } )
<label for="TermsAndConditions_false">No</label>
<br />
@Html.ValidationMessage( "TermsAndConditionsAgreement" )
</div>
<div>
<input id="CreateAccount" type="submit" name="submit" value="Create Account" />
</div>
}
Run Code Online (Sandbox Code Playgroud)
奖励:您会注意到我在单选按钮上添加了一些额外的功能.我使用的HTML label
元素的for
属性设置为每个单选按钮的ID,而不是仅使用纯文本作为单选按钮标签.这使用户可以单击标签来选择单选按钮,而不必单击单选按钮本身.这是标准的HTML.为了实现这一点,我必须在单选按钮上设置手动ID,否则它们都将获得相同的ID"仅限条款和条件",这是行不通的.
小智 15
您需要在此处执行一些操作,以确保在服务器端验证后维护用户的选择.
a)将每个无线电的"已检查"属性绑定到视图中的模型,例如:
Yes
@Html.RadioButtonFor(model => model.TermsAndConditions, "True", model.TermsAndConditions == true ? new { Checked = "checked" } : null)
No
@Html.RadioButtonFor(model => model.TermsAndConditions, "False", model.TermsAndConditions == false ? new { Checked = "checked" } : null)
Run Code Online (Sandbox Code Playgroud)
b)要在首次显示视图时定义初始默认值,请在GET请求中(在控制器操作中)初始化返回到视图的模型,例如:
public ActionResult SomeForm()
{
return View(new SomeModel { TermsAndConditions = false });
}
Run Code Online (Sandbox Code Playgroud)
b)确保在[HttpPost]控制器操作中,在验证失败时返回模型,例如:
[HttpPost]
public ActionResult SomeForm(SomeModel model)
{
if (!ModelState.IsValid)
return View(model);
// Do other stuff here
}
Run Code Online (Sandbox Code Playgroud)
这种方式在验证失败后在响应中呈现视图时,它将具有传入的实际模型状态(从而保持用户的选择).
归档时间: |
|
查看次数: |
91366 次 |
最近记录: |