MVC 3 - Model Binding a list in a table with each record being a column instead of row

独自空忆成欢 提交于 2019-12-02 12:24:44

问题


I can find various articles about how to model-bind a list of items in MVC 3, even from within a table, but in each example the rows represent a record in the list. The requirements for my view are that each record must be a column. I cannot get any of the tricks from the following articles working:

http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ http://dotnetslackers.com/articles/aspnet/Understanding-ASP-NET-MVC-Model-Binding.aspx#s8-binding-with-a-list-of-class-types

Here is the relevent part of my view:

    <table>
        <thead>
            <tr>
                <th>Name</th>
@foreach (var fact in Model.Facts)
{
                <th>@fact.Name</th>
}
            </tr>
        </thead>
        <tr>
            <td>Value</td>
@foreach (var fact in Model.Facts)
{
            <td>@Html.TextBox("Value" + fact.FactID.ToString(), fact.Value)</td>
}
        </tr>
        <tr>
            <td>Sample</td>
@foreach (var fact in Model.Facts)
{
            <td>@Html.TextBox("Sample" + fact.FactID.ToString(), fact.Sample)</td>
}
        </tr>
        <tr>
            <td>Default?</td>
@foreach (var fact in Model.Facts)
{
            <td>@Html.RadioButton("Default", fact.FactID, fact.Default)</td>
}
        </tr>
        <tr>
            <td></td>
@foreach (var fact in Model.Facts)
{
            <td>@Html.ActionLink("Detail", "Details", "Fact", new { id = fact.FactID }, null)</td>
}
        </tr>
    </table>

In the post action method for the form I am accepting a FormCollection which I am pulling data out of manually. Instead, I'd like to accept an IList collection and let the MVC model binder figure everything out for me.

Here is my controller action:

[HttpPost]
[Authorize]
public RedirectToRouteResult Facts(FormCollection form)
{
    int factListId = int.Parse(form["FactListID"]);
    FactList factList = Repository.Find(factListId);
    int defaultId = int.Parse(form["Default"]);
    foreach (Fact fact in factList.Facts)
    {
        string factId = fact.FactID.ToString();
        string toParse = form["Value" + factId];
        fact.Value = toParse.Length == 0 ? null : new Nullable<double>(double.Parse(toParse));
        fact.TextValue = form["Value" + factId];
        toParse = form["Sample" + factId];
        fact.Sample = toParse.Length == 0 ? null : new Nullable<int>(int.Parse(toParse));
        fact.Default = (fact.FactID == defaultId);
    }
    Repository.Save();
    return RedirectToAction("Index");
}

Anyone got something to point me in the right direction? I imagine there is information out there but I just can't find it in the huge volume of information about how to do this the more "standard" 1 row per record way.

Thanks


回答1:


If you have an IList then doing something like this should work. If you generate your inputs by numerical indexes, then you give MVC sufficient information to bind them on post.

@for (int i = 0; i< Model.Facts.Count(); i++)
{
      <td>@Html.TextBoxFor(m => m.Facts[i].Value)</td>
}

<--! Do other fields the same way -->

Your controller post action should accept a parameter that's of the same type as your ViewModel. Then you should see that the Facts IList has been bound correctly.



来源:https://stackoverflow.com/questions/10885679/mvc-3-model-binding-a-list-in-a-table-with-each-record-being-a-column-instead

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!