C# ASP.NET MVC单选按钮更新布尔值

C# ASP.NET MVC单选按钮更新布尔值,c#,asp.net-mvc,razor,radio-button,C#,Asp.net Mvc,Razor,Radio Button,我有一张表格: 用户可以在其中添加/更新/删除某人的姓名。姓名是PersonViewModel中的列表,我对主单选按钮有问题。我需要所有的名字都在一个radiobutton组中,只允许一个主要的名字 目前,如果我使用Html.RadioButtonFor,那么所有按钮都有不同的名称,因此不在同一组中,并且它们的IsPrimary布尔属性不会在回发中设置。我可以使用: <input type="radio" name="radioName"/> 这样可以保持分组正确,但我不确定

我有一张表格:

用户可以在其中添加/更新/删除某人的姓名。姓名是
PersonViewModel中的
列表
,我对
单选按钮有问题。我需要所有的名字都在一个radiobutton组中,只允许一个主要的名字

目前,如果我使用
Html.RadioButtonFor
,那么所有按钮都有不同的名称,因此不在同一组中,并且它们的
IsPrimary
布尔属性不会在回发中设置。我可以使用:

<input type="radio" name="radioName"/>


这样可以保持分组正确,但我不确定如何确保回发时正确设置IsPrimary boolean属性。有人能给我指点迷津吗?非常感谢

现在这是一个直截了当的问题。由于所有的
NameViewModel
项目都需要保持其唯一的名称,因此MVC模型绑定器可以正确识别和绑定您的模型。(我相信你已经猜到了)

因此,现在我们不需要单选按钮控件的名称来管理“组”。这个名称在HTTP Post中也用于标识控件的值。因此,现在我们处于第22条军规的位置,模型绑定器需要唯一的名称来绑定post上的模型,而浏览器需要所有相同的名称才能如您所述发挥作用

现在,您可以使用一些jQuery巫术来实现这一点,例如绑定另一个
数据-
,然后绑定到每个具有此名称的控件的click事件。现在我看到这更多的是一个黑客而不是一个解决方案,但可以这样做。(是的,这是基本的)

假设这个模型

public class PersonViewModel
{
    public PersonViewModel()
    {
        this.Names = new List<NameViewModel>();
    }

    public IList<NameViewModel> Names { get; set; }

}

public class NameViewModel
{
    public NameViewModel()
    {
        this.IsPrimary = false;
    }

    public int ID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string MiddleName { get; set; }

    public bool IsPrimary { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0}{1} {2}",
                                this.FirstName,
                                !string.IsNullOrWhiteSpace(this.MiddleName) ? " " + this.MiddleName : "",
                                this.LastName);
        }
    }
Javascript

$(function () {
        $('input[type="radio"][data-group="myGroup"]').click(function () {
            $('input[type="radio"][data-group="myGroup"]').removeAttr('checked');
            $(this).attr('checked', 'checked')
        });
    });
现在,这将给出您描述的结果。现在,另一种选择(假设使用了上面的模型)是向
PrimaryName
PersonViewModel
添加另一个属性,并将其设置为
NameViewModel
的ID(或主键)。使PersonViewModel看起来像

public class PersonViewModel
{
    public PersonViewModel()
    {
        this.Names = new List<NameViewModel>();
    }

    public IList<NameViewModel> Names { get; set; }

    public int PrimaryName { get; set; }
}
现在这也起作用了,但现在将PersonViewModel的“PrimaryName”设置为已检查的NameViewModel的ID。但是,您的
NameViewModel
将丢失帖子上的
IsPrimary
值,因为我们不会将该值传回。要做到这两个,你必须将两个选项结合起来


希望这能帮你找到正确的方向。任何一种方法(或其他方法)都应该有效。

不需要任何
JavaScript
。由于
Primary
是所有名称的公共属性,请按如下方式稍微更改
ViewModels

视图模型

公共类名称视图模型
{
公共int Id{get;set;}
[必需]
公共字符串名{get;set;}
公共字符串MiddleName{get;set;}
[必需]
公共字符串LastName{get;set;}
//其他属性
//...
}
公共类PersonViewModel
{
公共IList名称{get;set;}
[必需]
公共int?Primary{get;set;}
//其他属性
//...
}
控制器

public ActionResult Index()
{
var viewModel=newpersonviewmodel
{
名称=新列表
{
新名称视图模型{Id=1,FirstName=“Stephen”,MiddleName=“M”,LastName=“Abney”},
新名称视图模型{Id=2,FirstName=“Jim”,LastName=“Beam”}
}
};
返回视图(viewModel);
}
[HttpPost]
公共行动结果索引(PersonViewModel viewModel)
{
if(ModelState.IsValid)
{
NameViewModel primaryName=viewModel.Names.SingleOrDefault(m=>m.Id==viewModel.Primary);
//保存数据
}
返回视图(viewModel);
}
看法

@model PersonViewModel
...
@使用(Html.BeginForm())
{
@对于(int i=0;im.Names[i].FirstName)
@Html.ValidationMessageFor(m=>m.Names[i].FirstName)
@EditorFor(m=>m.Names[i].MiddleName)
@Html.ValidationMessageFor(m=>m.Names[i].MiddleName)
@Html.EditorFor(m=>m.Names[i].LastName)
@Html.ValidationMessageFor(m=>m.Names[i].LastName)
@Html.HiddenFor(m=>m.Names[i].Id)
@(m=>m.Primary,Model.Names[i].Id,新的{Id=“Primary”+i})
}
@Html.ValidationMessageFor(m=>m.Primary)
}

当然我简化了一点,但我想你明白了。

回答得很好。谢谢你的意见。我一直希望避免使用jquery,但您的解决方案确实有效(当我将最后一行更改为
$(this).prop('checked','checked')
用于我的较新jquery版本时),谢谢!很高兴它起作用了。很抱歉“道具”的改变,因为我刚刚使用了VSMVC4项目附带的库存标准。干杯
public class PersonViewModel
{
    public PersonViewModel()
    {
        this.Names = new List<NameViewModel>();
    }

    public IList<NameViewModel> Names { get; set; }

    public int PrimaryName { get; set; }
}
@Html.RadioButton("PrimaryName", name.ID, name.IsPrimary)
@Html.HiddenFor(x => x.Names[i].ID)
public class NameViewModel
{
    public int Id { get; set; }
    [Required]
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    [Required]
    public string LastName { get; set; }
    // other properties
    //...
}

public class PersonViewModel
{
    public IList<NameViewModel> Names { get; set; }
    [Required]
    public int? Primary { get; set; }
    // other properties
    //...
}
public ActionResult Index()
{
    var viewModel = new PersonViewModel
    {
        Names = new List<NameViewModel>
        {
            new NameViewModel {Id = 1, FirstName = "Stephen", MiddleName = "M", LastName = "Abney"},
            new NameViewModel {Id = 2, FirstName = "Jim", LastName = "Beam"}
        }
    };
    return View(viewModel);
}

[HttpPost]
public ActionResult Index(PersonViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        NameViewModel primaryName = viewModel.Names.SingleOrDefault(m => m.Id == viewModel.Primary);
        // save the data
    }
    return View(viewModel);
}
@model PersonViewModel
...
@using (Html.BeginForm())
{
    <div>
        <table>
            <tbody>
                @for (int i = 0; i < Model.Names.Count; i++)
                {
                    <tr>
                        <td>
                            @Html.EditorFor(m => m.Names[i].FirstName)
                            @Html.ValidationMessageFor(m => m.Names[i].FirstName)
                        </td>
                        <td>
                            @Html.EditorFor(m => m.Names[i].MiddleName)
                            @Html.ValidationMessageFor(m => m.Names[i].MiddleName)
                        </td>
                        <td>
                            @Html.EditorFor(m => m.Names[i].LastName)
                            @Html.ValidationMessageFor(m => m.Names[i].LastName)
                        </td>
                        <td>
                            @Html.HiddenFor(m => m.Names[i].Id)
                            @Html.RadioButtonFor(m => m.Primary, Model.Names[i].Id, new { id = "Primary_" + i })
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
    <div>
        @Html.ValidationMessageFor(m => m.Primary)
    </div>
    <div>
        <input type="submit" value="Save" />
    </div>
}