我有一个非常奇怪的错误,而且我绝对不知道它从哪里来。我要创建一个网页,您可以在其中修改表,并可以从该表中生成数据库中的表。为此,我正在使用ASP .NET MVC 4,并且已经能够在数据库中修改和创建表,但是我有一个小的“ +”按钮,我想在其中将单元格插入表(模型)中。 >
问题
它已经可以工作了,但是它总是将其插入到最后一个索引中,并且名称也等于前一个索引。 (与使用“-”按钮删除相同)
为实现这一点,我创建了两个模型:
我用一列初始化模型。 (我有更多不相关的属性和功能)
public class CreateTableModels
{
public CreateTableModels()
{
Columns = new List<CreateTableColumnModels>() { new CreateTableColumnModels(){ PrimaryKey = true } };
}
[Required]
[UniqueNamesValidation(ErrorMessage="Alle Namen müssen unique sein")]
[Display(Name = "Columns")]
public List<CreateTableColumnModels> Columns { get; private set; }
//more properties...
此模型具有 CreateTableColumnModels 列表:
public class CreateTableColumnModels
{
public CreateTableColumnModels()
{
Name = "name";
NotNull = false;
PrimaryKey = false;
Length = 1;
}
[Required]
[Display(Name = "Typ")]
public System.Data.SqlDbType Type { get; set; }
[Key]
[Required(ErrorMessage = "Darf nicht leer sein!")]
[RegularExpression(@"^[A-Za-z0-9]+$", ErrorMessage = "Nur Buchstaben und Zahlen sind erlaubt")]
[Display(Name = "Name")]
public string Name { get; set; }
//more properties...
在控制器中,我想在模型中插入一列(如果按下按钮,它将通过addCell发送索引)。该列的名称应为“已添加”。如果我添加新列,则效果很好。
public class CreateTableController : Controller
{
public ViewResult Index(CreateTableModels model, int count = 1, int? addCell = null, int? removeCell = null, bool createTable = false)
{
if (addCell != null)
{
model.Columns.Insert(addCell.Value, new CreateTableColumnModels() { Name = "ADDED", Type = System.Data.SqlDbType.Float });
}
我确实将几乎整个观点都放在了这里,因为我完全不知道问题所在。
<h2>CreateTable</h2>
@using (Html.BeginForm("Index", "CreateTable", FormMethod.Get))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true)
</div>
<table id="table" class="table">
<thead>
<tr>
<th>@Html.LabelFor(model => model.Columns.FirstOrDefault().Type)</th>
<th>@Html.LabelFor(model => model.Columns.FirstOrDefault().Length)</th>
<th>@Html.LabelFor(model => model.Columns.FirstOrDefault().Precision)</th>
<th>@Html.LabelFor(model => model.Columns.FirstOrDefault().Name)</th>
<th>@Html.LabelFor(model => model.Columns.FirstOrDefault().NotNull)</th>
<th>@Html.LabelFor(model => model.Columns.FirstOrDefault().PrimaryKey)</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < @Model.Columns.Count; i++)
{
<tr>
<td>
<div id="TableSelection">
@Html.DropDownListFor(m => Model.Columns[i].Type, new SelectList(Model.Columns[i].Types), new { @ID = "typeSelection", @class = "form-control", @style = "width:150px;" })
</div>
</td>
<td>
<div id="Length">
@Html.TextBoxFor(m => Model.Columns[i].Length, new { @ID = "length", @class = "form-control", @type = "number", @style = "width:80px", @disabled = "disabled" })
@Html.ValidationMessageFor(m => Model.Columns[i].Length)
</div>
</td>
<td>
<div id="Precision">
@Html.TextBoxFor(m => Model.Columns[i].Precision, new { @ID = "precision", @class = "form-control", @type = "number", @style = "width:80px", @disabled = "disabled" })
@Html.ValidationMessageFor(m => Model.Columns[i].Precision)
</div>
</td>
<td>
<div id="Name">
@Html.TextBoxFor(model => Model.Columns[i].Name, new { @class = "form-control", @style = "width:150px" })
@Html.ValidationMessageFor(model => Model.Columns[i].Name)
</div>
</td>
<td>
<div id="NotNull">
@Html.CheckBoxFor(model => Model.Columns[i].NotNull, new { @ID = "notNull", @checked = Model.Columns[i].NotNull, @class = "checkbox" })
</div>
</td>
<td>
<div id="PrimaryKey">
@Html.CheckBoxFor(x => Model.Columns[i].PrimaryKey, new { @ID = "primaryKey", @checked = Model.Columns[i].PrimaryKey, @class = "checkbox" })
</div>
</td>
<td>
<div>
<button type="submit" class="btn btn-default" name="addCell" value="@i">+</button>
<button type="submit" class="btn btn-default" name="removeCell" value="@i">-</button>
</div>
</td>
</tr>
}
</tbody>
</table>
<div align="left" class=" form-group" style="display: flex; flex-direction: row; justify-content: flex-start; align-items: center;">
<div>
@Html.LabelFor(model => model.TableName, new { @class = "control-label col-md-2" })
</div>
<div class="text-center control-form">
@Html.EditorFor(model => model.TableName, new { @class = "text-center control-form" })
@Html.ValidationMessageFor(model => model.TableName)
</div>
<div>
<button type="submit" style="margin-left:10px; margin-right:10px;" name="createTable" value="true" class="btn btn-success">Create</button>
</div>
<div>
@if (Model.WorkDone != null && (bool)Model.WorkDone)
{
<label style="font-size:medium" class="label label-success">Alle Änderungen wurden gespeichert!</label>
}
else if (Model.WorkDone != null)
{
<label style="font-size:medium" class="label label-danger">Es ist etwas schief gelaufen!</label>
}
</div>
</div>
}
我唯一能想到的改变是@RenderBody()
文件中的_Layout.cshtml
。有谁有类似的东西或可以帮助我吗?已经感谢您读完了:)
答案 0 :(得分:2)
问题在于,当您提交收藏集时,发布的值将添加到ModelState
中。如果我们仅查看Name
属性,则会添加以下值
Columns[0].Name // value = "a"
Columns[1].Name // value = "b"
Columns[2].Name // value = "c"
现在,您插入一个新列(例如在第一项之前)。现在模型中的值是
Columns[0].Name // value = "ADDED"
Columns[1].Name // value = "a"
Columns[2].Name // value = "b"
Columns[3].Name // value = "c"
现在,当您返回视图时,您(正确)使用了HtmlHelper
方法来生成视图,但是所有生成表单控件的HtmlHelper
方法都通过检查来呈现value
属性以下(按顺序)
ModelState
中的值(如果有)ViewDataDictionary
中的值(如果有)此行为的原因在TextBoxFor displaying initial value, not the value updated from code中进行了说明。
在for
循环的第一次迭代中,您的@Html.TextBoxFor(m => m.Columns[i].Name)
在ModelState
中看到“ a”的值,并在文本框中呈现“ a”(即使型号为“已添加”)。
在第二次迭代中,该值再次从ModelState
中获取,因此呈现了“ b”。
在第3次迭代中,该值再次从ModelState
中获取,因此呈现了“ c”。
在第4次也是最后一次迭代中,在ModelState
的{{1}}(或ViewData
)中找不到值,因此它从模型中读取值,因此“ c”呈现。
请注意,如果在表单元格中添加了Columns[3].Name
,则会看到根据属性值渲染的值,即第1行:“添加”,第2行:“ a”,第3行:“ b”,第4行:“ c”。
要解决此问题,您可以在返回视图之前添加@Model.Columns[i].Name
。但是,这样做的副作用是,它还会清除所有验证错误,因此至少ModelState.Clear()
无效时,您应该立即返回视图
ModelState
但是,最好的方法是遵循PRG模式并重定向到生成新数据的方法。