0

我知道这是非常标准的过程,但是由于对创建表的方式有一些自定义要求,我很难找到一种从表中读取数据并将其传递回控制器的方法。

我使用数据库中的记录构建我的表,每条记录都包含 rowNo 和 columnNo,问题是每个原始数据可能有不同的列数。我找不到合适的插件来构建它,所以我创建了一个简单的方法来创建一个传递给视图的字符串。

只是为了了解我在这里谈论的内容是代码中的一个片段,您可以在其中看到我是如何创建的<td>..</td>

sb.Append("<td>" + innerArray[a][0].QuestionText +
                                "<input type='textbox' value=" +
                                innerArray[a][0].FieldValue + "></td>");

我知道使用 StringBuilder 不是很聪明,+但现在它可以工作。因此,在构建我的字符串并将其传递给视图之后,我得到了这个:

在此处输入图像描述

这是来自View page source

 <tr>
     <td>alabala<input type='textbox' value=></td>
     <td colspan=2><input type='textbox' value=yes></td>
 </tr>
 <tr>
     <td colspan=3>alabala<input type='textbox' value=yes></td>
 </tr>
 <tr>
     <td colspan=3>alabala<input type='textbox' value=yes></td>
 </tr>
 <tr>
     <td>alabala<input type='textbox' value=no></td>
     <td>alabala<input type='textbox' value=no></td>
     <td>alabala<input type='textbox' value=no></td>
 </tr>
 <tr>
     <td>alabala<input type='textbox' value=no></td>
     <td colspan=2><input type='textbox' value=no></td>
 </tr>
 <tr>
     <td colspan=3>alabala<input type='textbox' value=></td>
 </tr>
 <tr>
     <td colspan=3>alabala<input type='textbox' value=no></td>
 </tr>

这就是你所看到的 - 一个包含整个 HTML 代码的长字符串。

所有文本框都是可编辑的,所以我需要一种方法来读取每个文本框的数据并将其与 RowNo 和 ColumnNo 一起保存/传递,以便我可以将其保存回我的数据库中。

4

2 回答 2

5

为什么不使用视图模型?您在控制器操作中使用此字符串构建器所做的事情绝对违背了您在 MVC 设计模式中可能拥有的所有良好实践。

因此,与往常一样,您可以从定义满足视图要求的视图模型开始:

public class ColViewModel
{
    public string RowNumber { get; set; }
    public string ColumnNumber { get; set; }
    public string QuestionText { get; set; }
    public string FieldValue { get; set; }
}

public class RowViewModel
{
    public List<ColViewModel> Columns { get; set; }
}

好的,现在让我们继续填充这个视图模型并将其传递给视图:

public ActionResult Index()
{
    // in your question you have shown something called innerArray, so I assume you
    // already retrieved this from your database or something:
    SomeDomainModel[,] innerArray = ...

    var model = new List<RowViewModel>();
    for (var row = 0; row < innerArray.GetUpperBound(0); row++)
    {
        var rowModel = new RowViewModel
        {
            Columns = new List<ColViewModel>()
        };
        for (var col = 0; col < innerArray.GetUpperBound(1); col++)
        {
            rowModel.Columns.Add(new ColViewModel
            {
                RowNumber = innerArray[row, col].RowNo,
                ColumnNumber = innerArray[row, col].ColumnNo,
                QuestionText = innerArray[row, col].Question,
                FieldValue = innerArray[row, col].FieldValue,
            });
        }
        model.Add(rowModel);
    }

    return View(model);
}

[HttpPost]
public ActionResult Index(List<RowViewModel> model)
{
    ...
}

最后在您相应的强类型视图中:

@model List<RowViewModel>
@using (Html.BeginForm())
{
    <table>
        @for (var i = 0; i < Model.Count; i++)
        {
            <tr>
                @for (var j = 0; j < Model[i].Columns.Count; j++)
                {
                    <td>
                        @Html.HiddenFor(x => x[i].Columns[j].RowNumber)
                        @Html.HiddenFor(x => x[i].Columns[j].ColumnNumber)
                        @Html.DisplayFor(x => x[i].Columns[j].QuestionText)
                        @Html.EditorFor(x => x[i].Columns[j].FieldValue)
                    </td>
                }
            </tr>
        }
    </table>

    <button type="submit">Save</button>
}
于 2013-04-25T06:57:26.170 回答
2

不要将 html 传递给您的视图。这是视图的责任。我首先会质疑您的数据库的架构(为什么数据库关心数据将如何由视图表示?)。假设我们在那里没有改变任何东西。这样做的方法是创建一个视图模型。我无法使用您提供给我们的信息对其进行编码(来自数据库的数据格式是什么?)。但这里是伪代码。

  1. 控制器从数据库中检索记录
  2. Controller 为每个行记录创建一个 View Model(我们称之为 RowModel)并用列数据填充它。你最终得到一个列表。我们称之为 rowModels。
  3. 控制器使用该数据调用视图`return View(rowModels)
  4. @model List<RowModel>视图在代码顶部声明了 a 。
  5. 您的 Razor 代码在模型中的行中进行交互并构建 HTML。
  6. 创建另一个控制器 Action MyAction(List<RowModels)。这将在提交时调用。只需遍历行并执行所需的任何数据库更新。

使用视图模型的另一个优点是您可以指定将用于字段的验证,而不是依赖(可能缺少)数据库模型验证。看到这个

于 2013-04-25T06:56:50.327 回答