У меня есть модель (RecruitingForm) с некоторыми полями (например: DepartmentId) и подсписком ICollection (RecruitingFormsRows). Я инициализирую объект таким образом и отправляю его в представление.
RecruitingForm model = new RecruitingForm();
for (int i = 0; i <= 3; i++)
{
RecruitingFormsRow modelRow = new RecruitingFormsRow();
model.RecruitingFormsRows.Add(modelRow);
}
LoadViewData(); //Loads the date for the combo boxes in ViewData
return View("AddRecruitingForm", model);
Переменные, которые находятся в главном объекте, установлены правильно при загрузке или (если ошибка) при ответе, но один раз, когда внутри ICollection (RecruitingFormsRows) нет в обоих случаях. Мой взгляд выглядит следующим образом:
@model RecruitingForms.Database_models.RecruitingForm
using (Html.BeginForm("AddRecruitingForm", "RecruitingForms"))
{
@Html.ValidationSummary(true)
@Html.DevExpress().FormLayout(settings =>
{
settings.Name = "AddRecruitingForm";
settings.Width = Unit.Pixel(1024);
var groupItem = settings.Items.AddGroupItem(groupSettings =>
{
groupSettings.CellStyle.Font.Bold = true;
groupSettings.Caption = @Resources.Resource.RecruitingForm;
groupSettings.ShowCaption = DefaultBoolean.True;
groupSettings.GroupBoxDecoration = GroupBoxDecoration.Default;
});
groupItem.SettingsItems.ShowCaption = DefaultBoolean.True;
groupItem.SettingsItemCaptions.Location = LayoutItemCaptionLocation.Top;
groupItem.SettingsItemHelpTexts.Position = HelpTextPosition.Top;
var groupItemLayer2 = groupItem.Items.AddGroupItem(groupSettings =>
{
groupSettings.CellStyle.Font.Bold = true;
groupSettings.ShowCaption = DefaultBoolean.True;
groupSettings.Caption = "";
groupSettings.GroupBoxDecoration = GroupBoxDecoration.Default;
groupSettings.ColumnCount = 3;
groupSettings.SettingsItems.HorizontalAlign = FormLayoutHorizontalAlign.Center;
});
groupItemLayer2.Items.Add(m => Model.DepartmentId, item =>
{
item.Caption = Resources.Resource.Department;
item.CaptionStyle.Font.Bold = true;
item.NestedExtension().ComboBox(comboBox =>
{
comboBox.Name = "DepartmentId";
comboBox.Properties.TextField = "Text";
comboBox.Properties.ValueField = "Value";
comboBox.Properties.ValueType = typeof(int);
comboBox.Properties.DataSource = ViewData["Departments"];
comboBox.ShowModelErrors = true;
comboBox.PreRender = (s, e) =>
{
MVCxComboBox cb = (MVCxComboBox)s;
if (!(cb.SelectedIndex > 0) || cb.Value.ToString() == "0")
{
cb.SelectedIndex = 0;
}
};
});
});
var groupItemLayer3 = groupItem.Items.AddGroupItem(groupSettings =>
{
groupSettings.CellStyle.Font.Bold = true;
groupSettings.ShowCaption = DefaultBoolean.True;
groupSettings.Caption = Resources.Resource.Required;
groupSettings.GroupBoxDecoration = GroupBoxDecoration.Default;
groupSettings.ColumnCount = 1;
groupSettings.SettingsItems.HorizontalAlign = FormLayoutHorizontalAlign.Left;
});
for (int i = 0; i < Model.RecruitingFormsRows.Count - 1; i++) //for some reason it runs once at the end of full file generation and it triggers index out of collection error
{
var groupItemLayer4 = groupItemLayer3.Items.AddGroupItem(groupSettings =>
{
groupSettings.CellStyle.Font.Bold = true;
groupSettings.ShowCaption = DefaultBoolean.True;
groupSettings.Caption = Resources.Resource.EmployeesOnFunction + " " + (i+1);
groupSettings.GroupBoxDecoration = GroupBoxDecoration.Default;
groupSettings.Width = Unit.Percentage(100);
groupSettings.ColumnCount = 2;
groupSettings.SettingsItems.HorizontalAlign = FormLayoutHorizontalAlign.Left;
});
groupItemLayer4.Items.Add(m => Model.RecruitingFormsRows.ToList()[i].CategoryId, item =>
{
item.Caption = Resources.Resource.Category;
item.CaptionStyle.Font.Bold = true;
item.NestedExtension().ComboBox(comboBox =>
{
comboBox.Properties.TextField = "Text";
comboBox.Properties.ValueField = "Value";
comboBox.Properties.ValueType = typeof(int);
comboBox.Properties.DataSource = @ViewData["Categories"];
comboBox.ShowModelErrors = true;
comboBox.Width = Unit.Percentage(100);
comboBox.PreRender = (s, e) =>
{
MVCxComboBox cb = (MVCxComboBox)s;
if (!(cb.SelectedIndex > 0) || cb.Value.ToString() == "0")
{
cb.SelectedIndex = 0;
}
};
});
});
groupItemLayer4.Items.Add(m => Model.RecruitingFormsRows.ToList()[i].NumberOfPersons, item =>
{
item.Caption = Resources.Resource.NumberOfPersons;
item.CaptionStyle.Font.Bold = true;
item.NestedExtension().TextBox(textBox =>
{
textBox.Width = Unit.Percentage(100);
textBox.ShowModelErrors = true;
});
});
}
groupItemLayer3.Items.Add(item =>
{
item.Width = Unit.Pixel(160);
item.Caption = "";
item.HorizontalAlign = FormLayoutHorizontalAlign.Center;
item.NestedExtension().Button(s =>
{
s.Name = "SubmitFormButton";
s.Text = Resources.Resource.Send;
s.UseSubmitBehavior = true;
s.Width = Unit.Pixel(150);
});
});
}).GetHtml()
Я получаю сообщение в таком контроллере, потому что не могу понять, почему оно не связывает строки с основной моделью.
[HttpPost, ValidateInput(true)]
public ActionResult AddRecruitingForm(RecruitingForm item, List<RecruitingFormsRow> itemRows)
{
DateTime dateTimeNow = DateTime.Now;
bool hasRowErrors = false;
for (int i = 0; i < itemRows.Count; i++)
{
if (itemRows[i].CategoryId > 0 && itemRows[i].NumberOfPersons > 0)
{
itemRows[i].Inserted_At = dateTimeNow;
itemRows[i].Updated_At = dateTimeNow;
item.RecruitingFormsRows.Add(itemRows[i]);
}
else if (itemRows[i].CategoryId > 0 && itemRows[i].NumberOfPersons == 0)
{
if (itemRows[i].NumberOfPersons == 0)
{
ViewData["EditRowError" + itemRows[i].Id] = Resources.Resource.NumberOfPersonsCantBe0;
}
item.RecruitingFormsRows.Add(itemRows[i]);
hasRowErrors = true;
}
}
if(hasRowErrors)
{
item.RecruitingFormsRows.Clear();
for (int i = 0; i < itemRows.Count; i++)
{
item.RecruitingFormsRows.Add(itemRows[i]);
//reload all the items received back into the whole model
}
RecruitingFormsRow modelRow = new RecruitingFormsRow();
item.RecruitingFormsRows.Add(modelRow);
LoadViewData(); //Loads the date for the combo boxes in ViewData
return View("AddRecruitingForm", item);
}
}
Моя главная проблема заключается в том, что если мне нужно вернуть сообщение об ошибке (например, у меня выбрана категория, но количество людей равно 0, тогда я должен отправить модель обратно в ответ с приложенным сообщением об ошибке), поля в списке устанавливаются вернуться к начальным значениям (0 и нуля).
Я проверил переменные с помощью отладчика, и значения дошли до представления в главном объекте (например: я установил CategoryId на 5 с использованием отладчика в функции get до Я отправил модель в представление и смог увидеть ее с помощью выражения ниже, чтобы значения попадали в представление, как ожидалось, но они не были установлены для самих объектов.
var test = Model.RecruitingFormsRows.ToList()[i].CategoryId;
Любая идея о том, что я я делаю что-то не так? Я пытался использовать foreach l oop вместо a для l oop, который правильно загружал представление, но позже я обнаружил, что невозможно опубликовать он ценит, потому что поля получают одно и то же имя.