#c_sharp #aspnet_mvc
Есть два метода для редактирования Первый передает значения для редактирования, а второй редактирует public ActionResult EditMagazine(int id) { var editMagazineModel = new EditMagazineViewModel() { Magazine = magazineService.EditMagazine(id) }; return View(editMagazineModel); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult EditMagazine1(EditMagazineViewModel magazine) { var magazineModel = new Magazine { MagazineId = magazine.Magazine.MagazineId, Name = magazine.Magazine.Name, Number = magazine.Magazine.Number, YearOfPublishing = magazine.Magazine.YearOfPublishing }; magazineService.EditMagazine1(magazineModel); return RedirectToAction("Magazine"); } из-за того что делаю ViewModel пришлось столкнуться с mapping'ом , так вот проблема в том что во втором методе выходит исключение из-за этого var magazineModel = new Magazine { я создаю новый обьект Кто подскажет как правильно передать значения с первого метода для второго метода [NullReferenceException: Object reference not set to an instance of an object.] Вот ViewModel public class EditMagazineViewModel { public Magazine Magazine { get; set; } } а вот Model public class Magazine { public int MagazineId { get; set; } public string Name { get; set; } public int Number { get; set; } public int YearOfPublishing { get; set; } } Вот View EditMagazine @model Library.ViewModel.MagazineViewModel.EditMagazineViewModel @{ Layout = "~/Views/Home/Layout.cshtml"; } @using (Html.BeginForm("EditMagazine1", "Magazine")) { @Html.AntiForgeryToken()}Magazine
@Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(model => model.Magazine.MagazineId)@Html.LabelFor(model => model.Magazine.Name, htmlAttributes: new { @class = "control-label col-md-2" })@Html.EditorFor(model => model.Magazine.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Magazine.Name, "", new { @class = "text-danger" })@Html.LabelFor(model => model.Magazine.Number, htmlAttributes: new { @class = "control-label col-md-2" })@Html.EditorFor(model => model.Magazine.Number, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Magazine.Number, "", new { @class = "text-danger" })@Html.LabelFor(model => model.Magazine.YearOfPublishing, htmlAttributes: new { @class = "control-label col-md-2" })@Html.EditorFor(model => model.Magazine.YearOfPublishing, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Magazine.YearOfPublishing, "", new { @class = "text-danger" })
Ответы
Ответ 1
Ваша модель основана на простых типах типа int и string: public class Magazine { public int MagazineId { get; set; } public string Name { get; set; } public int Number { get; set; } public int YearOfPublishing { get; set; } } При этом вы могли пойти по пути использования модели в качестве ViewModel - но раз уж вы пошли по пути ухода от модели - то не надо было во вьюмодели ссылаться на доменную логику: public class EditMagazineViewModel { public Magazine Magazine { get; set; } } Сделайте класс на простых типах: public class EditMagazineViewModel { public int MagazineId { get; set; } public string Name { get; set; } public int Number { get; set; } public int YearOfPublishing { get; set; } } (Чувствуете, что хочется записаться в сторонники использования моделей в качестве вьюмоделей? Код копипастится) Давайте теперь переделаем наш первый action: public ActionResult Edit(int id) { var magazine = magazineService.GetById(id); var model = new EditMagazineViewModel(magazine); return View(model); } и второй: [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(EditMagazineViewModel model) { if (!this.ModelState.IsValid) return this.View(model); var magazine = model.ToEntity(); magazineService.Update(magazine); return RedirectToAction("Magazine"); } (Обратите внимание: в сервис мы передаём уже доменную модель, сервис относится к слою бизнес-логики и может ничего не знать о десятках приложений (веб, мобильных) у каждого свои собственные вьюмодели) Только для этого нам нужно класс модели переписать следующим образом: public class EditMagazineViewModel { public EditMagazineViewModel() { } public EditMagazineViewModel(Magazine magazine) { this.MagazineId = magazine.MagazineId; this.Name = magazine.Name; this.Number = magazine.Number; this.YearOfPublishing = magazine.YearOfPublishing; } public Magazine ToEntity() { return new Magazine { MagazineId = this.MagazineId, Name = this.Name, Number = this.Number, YearOfPublishing = this.YearOfPublishing, }; } public int MagazineId { get; set; } public string Name { get; set; } public int Number { get; set; } public int YearOfPublishing { get; set; } } Первый конструктор нужен для asp.net, второй - для нас (чтобы не разбухал метод контроллера), а ToEntity - преобразует обратно ViewModel в Model. Понадобится - можете потом подтащить мапперы вместо этих методов. Остаётся переписать view: @model Library.ViewModel.MagazineViewModel.EditMagazineViewModel @{ Viewbag.Title = "Edit magazine"; }@Viewbag.Title
@using (Html.BeginForm("EditMagazine", "Magazine", FormMethod.Post)) { @Html.AntiForgeryToken()@Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(model => model.MagazineId)} У меня в тестовом приложении работает (естественно чуть другие неймспейсы), проблем нет:@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })@Html.LabelFor(model => model.Number, htmlAttributes: new { @class = "control-label col-md-2" })@Html.EditorFor(model => model.Number, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Number, "", new { @class = "text-danger" })@Html.LabelFor(model => model.YearOfPublishing, htmlAttributes: new { @class = "control-label col-md-2" })@Html.EditorFor(model => model.YearOfPublishing, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.YearOfPublishing, "", new { @class = "text-danger" })
Комментариев нет:
Отправить комментарий