【问题标题】:Pass a list of view models to mvc controller action将视图模型列表传递给 mvc 控制器操作
【发布时间】:2016-07-24 06:57:49
【问题描述】:

我在将视图数据序列化到视图模型对象时遇到问题,但不确定如何解决该问题。调试时控制器动作中的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>
}

【问题讨论】:

  • 对于这种情况,我发现将视图模型转换为 JSON 并将其作为字符串直接传递给控制器​​(例如,输入字段)通常是一个好主意。模型绑定似乎比复杂的 IEnumerable 数据类型更能解析 JSON 字符串。
  • @Bardo 仍然对如何解决问题有些困惑。你能就如何解决这个问题提供这个上下文的答案吗?

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


【解决方案1】:

当我想处理复杂的数据类型,并且我必须管理必须传递回控制器的数据集合时,我通常会这样做:

1) 为 viewModel 创建一个类(在这种情况下,它将是您的 SkeetSinglesScoreCards)。

2) 在客户端代码 (HTML) 上,我将这些数据的 JSON 版本加载到隐藏的输入中(有时 JSON 数据来自 viewModel 类,其他时候我在呈现页面时对其进行解析,这取决于业务模型)。

3) 在客户端代码 (javascript) 上,我将 JSON 数据加载到 javascript 对象中。对此对象的每个客户端操作都被考虑在内。在发布全局提交之前,我什么时候可以完全避免通过 AJAX 向服务器重新发送信息。

4) 当用户要求发布他的操作结果时,我在 javascript 上捕获事件,将存储信息的 javascript 对象字符串化并将其发布到隐藏的输入。然后发布表格。

5) 控制器签名期望一个类的元素可以从隐藏输入中存储的数据结构中推断出来,并且参数的名称与隐藏输入相同。

我发现这种方法效果很好

【讨论】:

    【解决方案2】:

    您当前的代码将生成名称类似于此模式的输入字段。

    scoreCards_0_sgl_H_1
    

    但是您的 HttpPost 操作方法接受 SkeetSinglesScoreCards 的对象,该对象具有 scorecard 属性。因此,您应该生成这样的 html 以使模型绑定起作用。

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

    这应该可行。

    @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" />
    }
    

    【讨论】:

      猜你喜欢
      • 2016-07-18
      • 1970-01-01
      • 2018-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多