【问题标题】:ViewModel not posting backViewModel 不回发
【发布时间】:2014-06-29 15:50:43
【问题描述】:

我的控制器中有这个:

public ActionResult Index()
{
    var viewModels = _dataSyncService.Get().Select(provider => new IndexViewModel
    {
        Selected = false, Provider = provider
    }).ToList();

    return View(viewModels);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(IEnumerable<IndexViewModel> viewModels)
{
    //Breakpoint on this to check viewModels
}

视图模型:

public class IndexViewModel
{
    public bool Selected { get; set; }

    public IDataSyncProvider Provider { get; set; }
}

还有我的 Index.cshtml:

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <button type="submit" class="btn blue">Trigger Selected</button>

    @foreach (var sync in Model)
    {
        <tr>
            <td>
                @Html.CheckBoxFor(s => sync.Selected)
            </td>
            <td>@sync.Provider.FriendlyName</td>
        </tr>
    }
}

但是我的模型被回发了,viewModels 总是返回为空。我读了很多关于必须将 ID 分配给复选框等的信息,但我认为这就是 Html.CheckBoxFor 的用途。

我确信我会在某个时候为此自责,但请提供一些指导。

【问题讨论】:

    标签: asp.net-mvc forms postback


    【解决方案1】:

    如果您想使用内置的 Html 帮助程序,例如 Html.CheckBoxFor,那么您需要使用 for 循环而不是 foreach,以便帮助程序呈现正确的输入名称:

    @for(int sync = 0; sync < Model.Count; sync++)
    {
        <tr>
            <td>
                @Html.CheckBoxFor(m => Model[sync].Selected)
            </td>
            <td>@Model[sync].Provider.FriendlyName</td>
        </tr>
    }
    

    您可以在此处阅读有关绑定到列表的更多信息:Model Binding To A List

    【讨论】:

    • 啊,我见过这样的例子,但我认为这只是他们的偏好。我试试看。
    • 这不是一个偏好。如果要绑定到集合,输入名称必须遵循链接文章中描述的方案。只有当您在其中使用数组索引器时,助手才会生成这些名称。因此,如果您维护一个单独的索引并在帮助程序中使用索引器,您仍然可以使用foreach,但在这种情况下,foreach 不会为您购买任何东西,因此使用简单的for 循环更容易。
    • 太好了,这已经对回发进行了排序(即当勾选并回发时 Selected = true)但是我的 ViewModel 的 Provider 部分没有回发。你知道为什么吗?我试过添加@Html.HiddenFor(m =&gt; Model[i].Provider),但这似乎没有帮助。 p.s 当 ViewModel 被分配给视图并被发送时,我已经检查了它。
    • @Html.HiddenFor(m =&gt; Model[i].Provider) 仅在您的 Provider 是简单类型时才有效。对于复杂类型,您必须列出其所有属性,例如 @Html.HiddenFor(m =&gt; Model[i].Provider.Prop1) @Html.HiddenFor(m =&gt; Model[i].Provider.Prop2) 等。但是 MVC 模型绑定不支持绑定到开箱即用的接口。因此,即使您指定了属性,它也不起作用。您需要编写自己的自定义模型绑定器,它可以绑定您的IDataSyncProvider,请参阅:stackoverflow.com/questions/10812880/…
    【解决方案2】:

    这是因为,您只是使用 return RedirectToAction("Index"); 重定向它

    在您的 POST 操作中

    试试:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Index(IEnumerable<IndexViewModel> viewModels)
    {
        return View(viewModels); 
    }
    

    希望会有所帮助。

    【讨论】:

    • 我已经编辑了我的帖子,因为它显然不清楚。我在那部分有一个断点,并在重定向之前检查viewModels 变量。
    • 这与 OP 的问题无关,正如 cmets 中所述,return RedirectToAction 代码只是一个示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    相关资源
    最近更新 更多