一个MVC3单选按钮绑定到一个模型的正确方法 [英] Correct way to bind an mvc3 radiobutton to a model

查看:144
本文介绍了一个MVC3单选按钮绑定到一个模型的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含我的网站的条款和条件单选按钮列表的视图。

I have a view that contains a radiobutton list for my terms and conditions of the site.

例如

Yes
@Html.RadioButtonFor(model => model.TermsAndConditions, "True")
No
@Html.RadioButtonFor(model => model.TermsAndConditions, "False",
     new { Checked = "checked" })
</div>
@Html.ValidationStyledMessageFor(model => model.TermsAndConditions)

如果用户完成形式,无任何错误,但是,如果我做服务器端验证和刷新页面我失去了单选按钮和选择电台取得了用户返回到默认为false场选择一切正常。

All is ok if the user completes the form without any errors however if I do serverside validation and the page is refreshed I lose the selection that the user made for the radiobutton and the selected radio goes back to the default false field.

我如何意味着要结合单选因此,如果用户选择真正该值,即使服务器端验证后维持?

How am I meant to be binding the radiobutton so if a user selects true this value is maintained even after serverside validation?

任何建议将是伟大的!

推荐答案

有关简短的回答,你需要做三件事情:

For the short answer, you need to do three things:


  1. 从第二个单选按钮删除新{选中=选中} 。这种硬codeD检查值将覆盖所有的魔力。

  2. 当您从控制器的行动回报您的ViewResult,给它你的模型类的一个实例,其中TermsAndConditions是假的。这将为您提供,以便有pselected适合你的假单选按钮$ P $需要的缺省值为false。

  3. 使用真正为您的单选按钮,而不是的值真。这是因为你的属性的类型为布尔的。严格地说,你不约而同地选择了正确的字符串重新presentations为真正,但该值参数该RadioButtonFor方法是键入对象的。这是最好的,你要比较,而不是将其转换为字符串自己的实际类型来传递。更多关于这下面。

  1. Remove the new { Checked = "checked" } from the second radio button. This hard-coded checked value will override all of the magic.
  2. When you return your ViewResult from the controller action, give it an instance of your model class where TermsAndConditions is false. This will provide the default false value you need in order to have the false radio button preselected for you.
  3. Use true and false as the values for your radio buttons instead of "True" and "False". This is because your property is of type bool. Strictly speaking, you coincidentally chose the correct string representations for true and false, but the value parameter for the RadioButtonFor method is of type object. It's best to pass in the actual type you want to compare to rather than converting it to a string yourself. More on this below.

下面是发生了什么事在深度:

Here's what's going on in depth:

该框架要自动完成这一切给你,但你没有那些最初的两件事情不正确的,这使得你与框架争取得到你想要的行为。

The framework wants to do all of this for you automatically, but you did those first two things incorrectly which makes you have to fight with the framework to get the behavior you want.

该RadioButtonFor方法调用的ToString()您指定的属性的值,并将其比作的ToString()的价值在创建单选按钮时传递。如果他们是平等的,那么它在内部设置器isChecked = TRUE 和最终渲染检查在HTML =选中 。这是怎么决定要检查哪些单选按钮。它简单的单选按钮的值进行比较的属性的值,并检查该相匹配的

The RadioButtonFor method calls .ToString() on the value of the property you specified and compares it to the .ToString() of the value you passed in when creating the radio button. If they are equal, then it internally sets isChecked = true and ends up rendering checked="checked" in the HTML. This is how it decides which radio button to check. It simply compares the value of the radio button to the value of the property and checks the one that matches.

您可以渲染pretty单选按钮太多的财产这种方式,它会神奇的工作。字符串,整数,甚至枚举类型的所有工作!具有的ToString返回其唯一重presents对象的值将工作一个字符串方法的对象。你只需要确保你的设置单选按钮的价值,你的财产可能实际上有一个值。要做到这一点,最简单的方法就是在值传递本身,而不是字符串重新的价值presentation。让框架将其转换为字符串为您服务。

You can render radio buttons for pretty much any property this way and it will magically work. Strings, ints, and even enum types all work! Any object that has a ToString method that returns a string which uniquely represents the object's value will work. You just have to make sure you're settings the radio button's value to a value that your property might actually have. The easiest way to do this is just to pass in the value itself, not the string representation of the value. Let the framework convert it to a string for you.

(既然你碰巧在正确的字符串重新presentations通过真正,然后这些值将工作,只要你修复你的两个实际的错误,但它仍然是明智的实际值,而不是他们的字符串传递。)

(Since you happened to pass in the correct string representations of true and false, then those values will work as long as you fix your two actual mistakes, but it's still wise to pass in the actual values and not their strings.)

您的第一个真正的错误是硬编码选中=选中为否单选按钮。这将覆盖哪些框架正在试图为你做的,导致总是被选中此单选按钮。

Your first real mistake was hard-coding Checked = "checked" for the "No" radio button. This will override what the framework is trying to do for you and results in this radio button always being checked.

显然,你想要的否单选按钮是preselected,但你必须做的方式,与上述所有设备兼容。你需要给视图,其中TermsAndConditions设置为false模型类的实例,并让它绑定,为单选按钮。通常情况下,这是为了响应一个URL的初始GET请求控制器动作并没有给视图模型类的实例都没有。通常情况下,你只需返回查看(); 。不过,既然你要选择一个默认值,则必须提供您的模型有设置为false TermsAndConditions的实例的视图。

Obviously you want the "No" radio button to be preselected, but you have to do it in a way that's compatible with everything above. You need to give the view an instance of your model class where TermsAndConditions is set to false, and let it "bind" that to the radio buttons. Normally, a controller action which responds to the initial GET request of a URL doesn't give the View an instance of the model class at all. Typically, you just return View();. However, since you want a default value selected, you must provide the view with a instance of your model that has TermsAndConditions set to false.

下面是说明这一切的一些源$ C ​​$ C:

Here is some source code illustrating all of this:

某种Account类的,你可能已经拥有。 (您的视图模型):

Some sort of Account class that you probably already have. (Your View's model):

public class Account
{
    public bool TermsAndConditions { get; set; }
    //other properties here.
}

在你的控制器的一些方法:

Some methods in your controller:

//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();
}

整个视图:

@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>
}

奖金:您会发现,我添加了一些额外的功能,单选按钮。而不是只使用纯文本单选按钮标签,我使用​​的HTML 标签属性设置为元素每个单选按钮的ID。这使用户可以在标签上单击以选中,而不必点击单选按钮本身的单选按钮。这是标准的HTML。对于这个工作,我不得不在电台按钮设置手动的ID,否则他们将都得到公正TermsAndConditions的同一个ID,这是行不通的。

BONUS: You'll notice that I added a little extra feature to the radio buttons. Rather than just use plain text for the radio button labels, I used the HTML label element with the for attribute set to the IDs of the each radio button. This lets users click on the label to select the radio button instead of having to click on the radio button itself. This is standard HTML. For this to work I had to set manual IDs on the radio buttons, otherwise they would both get the same ID of just "TermsAndConditions", which wouldn't work.

这篇关于一个MVC3单选按钮绑定到一个模型的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆