将视图模型列表传递给mvc控制器操作

时间:2016-04-04 16:09:25

标签: c# asp.net-mvc razor viewmodel

我遇到了将视图数据序列化到我的viewmodel对象并且不确定如何解决问题的问题。调试时,控制器操作中的scoreCards为空。

控制器动作:

public ActionResult SaveSkeetSinglesScores(SkeetSinglesScoreCards scoreCards) {
        return View();
    }

查看包含传递到控制器(SkeetSinglesScoreCards)的列表的模型:

public class SkeetSinglesScoreCards {
    public List<SkeetSinglesScoreCard> scoreCards { get; set; }
}

个人SkeetSinglesScoreCard视图模型:

public class SkeetSinglesScoreCard {
    public string sgl_H_1 {get; set; }
    public string sgl_L_1 { get; set; }
    public string dbl_H_1 { get; set; }
    public string dbl_L_1 { get; set; }
    public string sgl_H_2 { get; set; }
    public string sgl_L_2 { get; set; }
    public string dbl_H_2 { get; set; }
    public string dbl_L_2 { get; set; }
    public string sgl_H_3 { get; set; }
    public string sgl_L_3 { get; set; }
    public string sgl_H_4 { get; set; }
    public string sgl_L_4 { get; set; }
    public string sgl_H_5 { get; set; }
    public string sgl_L_5 { get; set; }
    public string sgl_H_6 { get; set; }
    public string sgl_L_6 { get; set; }
    public string dbl_H_6 { get; set; }
    public string dbl_L_6 { get; set; }
    public string sgl_H_7 { get; set; }
    public string sgl_L_7 { get; set; }
    public string dbl_L_7 { get; set; }
    public string dbl_H_7 { get; set; }
    public string H_8 { get; set; }
    public string L_8 { get; set; }
    public string opt { get; set; }
}

最后我的视图我将数据发布到控制器操作:

@using (Html.BeginForm("SaveSkeetSinglesScores", "Scores", FormMethod.Post)) {
    foreach (var round in Model) {
    <table class="table table-bordered">

        <thead>
            <tr class="active">
               <!--table headers here--!>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_H_1")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit1StationOneSinglesHigh)" />
                </td>

                <td>
                    <input name="@("scoreCards_"+i+"_sgl_L_1")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit2StationOneSinglesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_dbl_H_1")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit3StationOneDoublesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_dbl_L_1")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit4StationOneDoublesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_H_2")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit5StationTwoSinglesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_L_2")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit6StationTwoSinglesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_dbl_H_2")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit7StationTwoDoublesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_dbl_L_2")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit8StationTwoDoublesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_H_3")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit9StationThreeSinglesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_L_3")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit10StationThreeSinglesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_H_4")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit11StationFourSinglesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_L_4")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit12StationFourSinglesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_H_5")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit13StationFiveSinglesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_L_5")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit14StationFiveSinglesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_H_6")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit15StationSixSinglesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_L_6")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit16StationSixSinglesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_dbl_H_6")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit17StationSixDoublesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_dbl_L_6")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit18StationSixDoublesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_H_7")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit19StationSevenSinglesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_sgl_L_7")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit20StationSevenSinglesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_dbl_L_7")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit21StationSevenDoublesLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_dbl_H_7")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit22StationSevenDoublesHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_H_8")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit23StationEightHigh)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"_L_8")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.Hit24StationEightLow)" />
                </td>
                <td>
                    <input name="@("scoreCards_"+i+"opt")" type="text" maxlength="1" size="1" value="@ScoreHitMisConverter.IsHitToTableRowValue(round.OptionScore)" />
                </td>
                <td class="text-center total">0</td>
                @{i++;}
            </tr>
        </tbody>

    </table>

}
<button class="btn btn-default" type="submit" value="Save">Save</button>
}

2 个答案:

答案 0 :(得分:2)

Your current code will generate input field's with name like this pattern.

scoreCards_0_sgl_H_1

But your HttpPost action method accepts an object of SkeetSinglesScoreCards, which has a scorecard property. So you should generate html like this for model binding to work.

<input name="scoreCards[0].sgl_H_1" value="somthing" />
<input name="scoreCards[1].sgl_H_1" value="somthing" />

This should work.

@using (Html.BeginForm())
{
    var i = 0;
    foreach (var skeetSinglesScoreCard in Model.scoreCards)
    {    
        <input name="scoreCards[@i].sgl_H_1" type="text" value="someValue" />
        i++;
    }
    <input type="submit" value="Submit form" />
}

答案 1 :(得分:2)

When I want to work with complex data types, and I have to manage data collections that have to be passed back to the controller this is how I usually proceed:

1) Create a class for the viewModel (in this case it would be your SkeetSinglesScoreCards).

2) On client code (HTML) I load a JSON version of those data into a hidden input (sometimes the JSON data came from the viewModel class, other times I parse it when rendering the page, it depends on the business model).

3) On client code (javascript) I load the JSON data into a javascript object. Every client operation is taken into account over this object. When I can I totally avoid resending info to server through AJAX until global submit is posted.

4) When the user asks to post the result of his operations I capture the event on javascript, stringify the javascript object where info is stored and post it to the hidden input. Then post the form.

5) Controller signature expects for an element of a class that can be inferred from the data structure stored in the hidden input, and the name of the parameter is the same as the hidden input.

I've found this method to work quite well