Short overview
I have a very curious bug and I have absolutetly no idea where it is coming from. I want to create a webpage, where you can modify a table and out of this table you can generate a table in the database. For that I am using ASP .NET MVC 4 and I am already able to modify and create the table in the database, but I have a small "+" button, where I want to insert cells into the table (model).
Problem
It already works, but it is inserting it always at the last index AND the name is also equal to the one, which was last before. (same for deleting with "-" button)
Here two screenshots:
Before clicking:
After clicking:
Code
To achieve that all I have created two models:
CreateTableModel
I initialize the Model with one column. (I have more proerties and functions which are not relevant)
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...
This Model has a list of 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...
Controller
In the controller i want to insert a column to the model (if the button was pressed it sends the index via addCell). The column should have the name "Added". If I Add a new column it works fine.
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 });
}
View
I did put nearly the whole view here, because I have absolutely no clue where the problem is located.
<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>
}
Debug
Also if I debug it till the end of the view, it has the right values.
The only thing I can imagine changing it is the @RenderBody()
in the _Layout.cshtml
file. Is there anyone who had something similar or can help me? Already thanks for reading to the end :)