#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" })
Комментариев нет:
Отправить комментарий