MVC3 使用 CheckBox 和复杂的视图模型

发布于 2024-11-01 21:12:06 字数 1476 浏览 2 评论 0原文

对了,伙计们。我需要你的智慧,因为我找不到正确的方法。

我有一个视图模型:

public class EditUserViewModel
{
    public User User;
    public IQueryable<ServiceLicense> ServiceLicenses;
}

用户并不重要,因为我知道如何处理它。

ServiceLicenses 具有以下实现:

public class ServiceLicense
{
    public Guid ServiceId { get; set; }
    public string ServiceName { get; set; }
    public bool GotLic { get; set; }
}

获取已检查的用户列表很酷。它就像一个魅力。

<fieldset>
    <legend>Licenses</legend>
    @foreach (var service in Model.ServiceLicenses)
    {     
    <p>
        @Html.CheckBoxFor(x => service.GotLic)
        @service.ServiceName
    </p>
    } 
</fieldset>

我遇到的问题是将更新后的 ServiceLicenses 对象与新检查的服务返回到我的控制器中的 HttpPost 。为了简单起见,我们可以说它看起来像这样:

    [HttpPost]
    public ActionResult EditUser(Guid id, FormCollection collection)
    {

        var userModel = new EditUserViewModel(id);
        if (TryUpdateModel(userModel))
        {
            //This is fine and I know what to do with this
            var editUser = userModel.User;

            //This does not update
            var serviceLicenses = userModel.ServiceLicenses;

            return RedirectToAction("Details", new { id = editUser.ClientId });
        }
        else
        {
            return View(userModel);
        }
    }

我知道我使用 CheckBox 的方式是错误的。我需要更改什么才能更新服务许可证并在表单中选中复选框?

Right guys. I need your brains as I can't find a way to do this properly.

I have a view model:

public class EditUserViewModel
{
    public User User;
    public IQueryable<ServiceLicense> ServiceLicenses;
}

User is unimportant as I know how to deal with it.

ServiceLicenses has the following implementation:

public class ServiceLicense
{
    public Guid ServiceId { get; set; }
    public string ServiceName { get; set; }
    public bool GotLic { get; set; }
}

Getting a checked list of users is cool. It works like a charm.

<fieldset>
    <legend>Licenses</legend>
    @foreach (var service in Model.ServiceLicenses)
    {     
    <p>
        @Html.CheckBoxFor(x => service.GotLic)
        @service.ServiceName
    </p>
    } 
</fieldset>

The problem I'm having is getting the updated ServiceLicenses object with new checked services back to the HttpPost in my controller. For simplicity lets say it looks like this:

    [HttpPost]
    public ActionResult EditUser(Guid id, FormCollection collection)
    {

        var userModel = new EditUserViewModel(id);
        if (TryUpdateModel(userModel))
        {
            //This is fine and I know what to do with this
            var editUser = userModel.User;

            //This does not update
            var serviceLicenses = userModel.ServiceLicenses;

            return RedirectToAction("Details", new { id = editUser.ClientId });
        }
        else
        {
            return View(userModel);
        }
    }

I know I am using CheckBox the wrong way. What do I need to change to get serviceLicenses to update with the boxes checked in the form?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

话少心凉 2024-11-08 21:12:06

我知道 ServiceLicenses 属性是一个集合,您希望 MVC 绑定器将其绑定到您的操作参数属性。为此,您应该在视图中的输入中附加索引,例如

<input type="checkbox" name = "ServiceLicenses[0].GotLic" value="true"/>
<input type="checkbox" name = "ServiceLicenses[1].GotLic" value="true"/>
<input type="checkbox" name = "ServiceLicenses[2].GotLic" value="true"/>

前缀可能不是强制性的,但在绑定操作方法参数的集合属性时非常方便。为此,我建议使用 for 循环而不是 foreach,并使用 Html.CheckBox 帮助程序而不是 Html.CheckBoxFor

<fieldset>
    <legend>Licenses</legend>
    @for (int i=0;i<Model.ServiceLicenses.Count;i++)
    {     
    <p>
        @Html.CheckBox("ServiceLicenses["+i+"].GotLic",ServiceLicenses[i].GotLic)
        @Html.CheckBox("ServiceLicenses["+i+"].ServiceName",ServiceLicenses[i].ServiceName)//you would want to bind name of service in case model is invalid you can pass on same model to view
        @service.ServiceName
    </p>
    } 
</fieldset>

不使用强类型帮助程序只是个人偏好。如果您不想像这样对输入进行索引,您也可以看看这个很棒的 帖子 作者:steve senderson

编辑: 我有关于创建主详细信息的博客 asp.net mvc3 上的表单,这也与列表绑定相关。

i understand that ServiceLicenses property is a collection and you want MVC binder to bind it to you action parameters property. for that you should have indices attached with inputs in your view e.g

<input type="checkbox" name = "ServiceLicenses[0].GotLic" value="true"/>
<input type="checkbox" name = "ServiceLicenses[1].GotLic" value="true"/>
<input type="checkbox" name = "ServiceLicenses[2].GotLic" value="true"/>

Prefix may not be mandatory but it is very handy when binding collection property of action method parameter. for that purpose i would suggest using for loop instead of foreach and using Html.CheckBox helper instead of Html.CheckBoxFor

<fieldset>
    <legend>Licenses</legend>
    @for (int i=0;i<Model.ServiceLicenses.Count;i++)
    {     
    <p>
        @Html.CheckBox("ServiceLicenses["+i+"].GotLic",ServiceLicenses[i].GotLic)
        @Html.CheckBox("ServiceLicenses["+i+"].ServiceName",ServiceLicenses[i].ServiceName)//you would want to bind name of service in case model is invalid you can pass on same model to view
        @service.ServiceName
    </p>
    } 
</fieldset>

Not using strongly typed helper is just a personal preference here. if you do not want to index your inputs like this you can also have a look at this great post by steve senderson

Edit: i have blogged about creating master detail form on asp.net mvc3 which is relevant in case of list binding as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文