简体   繁体   中英

How to get a list/array from a view back to the controller

My ViewResult Controller:

    public ViewResult Controller(int id)
    {
        List<Data> dataList = dataAccess.getDataById(id);
        Results[] resultArray = new Results[dataList.Count];
        ViewBag.results= resultArray;
        return View(dataList);
    }

My View:

@model IEnumerable<Solution.Models.Data>

@{
    Solution.Models.Results[] res= ViewBag.results;
}


@using (Html.BeginForm()) {
<table>
@{

    int i = 0;
    foreach (var item in Model) {
    <tr>
        <td>
            Snippet: @Html.DisplayFor(modelItem => item.text)
        </td>

    </tr>
    <tr>
        <td>
            Translation: @Html.EditorFor(modelItem => res[i].text)
        </td>
    </tr>
    i++;
    }
}
</table>
<p>
    <input class="CRUD-buttons" type="submit" value="Send" />
</p>
}

My Controller ActionResult:

    [HttpPost]
    public ActionResult Controller(/*List<Data> dataList, */Results[] results)
    {
        ResultText = results[0].text; //NullReferenceException
    }

dataList and results are empty. I read a couple of posts on stackoverflow, but could not find a solution.

I took already a look on the following blog ( link ) but its MVC 2 code. :(

There are multiple ways to do this. What gets you here is that in order for you to receive the results parameter, the name for the generated edit controls should be results[0] for the first, results[1] for the second, etc with no gaps in the indexes (this is because of how DefaultModelBinder expects to find the fields named when the form is posted).

So one immediate (although not very good) solution would be to specify the name correctly:

@Html.TextBox(string.Format("results[{0}]", i), res[i].text)

A much better solution would be to put the results into your model (better yet, in a ViewModel created specifically for this view). For example, first of all you create a class that encapsulates one piece of data and the corresponding result:

class ItemViewModel
{
    Solution.Models.Data TheData { get; set; }
    Solution.Models.Results TheResults { get; set; }
}

You then make your view have a collection of these items as its model:

@model IEnumerable<ItemViewModel>

and then output the edit control with

Translation: @Html.EditorFor(modelItem => modelItem.TheResults)

Finally, you modify the postback action to accept an array of ItemViewModel :

[HttpPost] 
public ActionResult Controller(ItemViewModel[] results) 

General piece of advice: Try to avoid using EditorFor with objects that are not part of your view's model (for example, things you have passed through ViewBag or ViewData ). If you do this, MVC will punish you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM