如何使用视图模型作为控制器方法属性更新特定的数据库条目
How do I update a specific database entry with a view model as controller method attribute
我的网站中有一个输入 table,它连接到一个视图模型。在控制器方法中,我将此视图模型传递给控制器,反之亦然,这意味着控制器使用数据库中的数据填充视图模型,视图 returns 填充用户可能输入的表单数据的视图模型.
问题是,一旦视图接收到视图模型对象,数据库中的 "ID" 属性就不再存在。调用 Post 方法时,无法知道必须更新哪个数据库条目。
我的问题是:当我将视图模型传递给控制器方法时,如何更新特定的数据库条目?
示例控制器方法:
[HttpPost]
public ActionResult method(ViewModel vm)
{
DataContext.Context.Where(x => x.ID == vm.Object.ID) // this is where vm.Object.ID always returns "0", not the actual ID from the database entry
Context.SaveChanges();
return View(vm);
}
如果您需要更多信息,请告诉我。此外,使用 jquery 不是该项目的可行选择。非常感谢您的帮助!
编辑:
查看:
@model MyANTon.ViewModels.Q4_Answer_VM
@{
ViewBag.Title = "myANTon Anforderungserfassung";
ViewBag.HideNavBar = false;
}
@using (Html.BeginForm())
{
<div class="container">
<div class="jumbotron">
<hr />
<table class="grid" id="datatable">
<tr>
<th>Nr.</th>
<th>Last</th>
<th>Quelle</th>
<th>Ziel</th>
<th>Frequenz [/h]</th>
<th>Abstand [m]</th>
<th></th>
<th></th>
@{int i = 1; }
@for (var a = 0; a < Model.Matrix.Count; a++)
{
<tr>
<td>@(i++)</td>
<td>@Html.TextBoxFor(x => Model.Matrix[a].Load)</td>
<td>@Html.TextAreaFor(x => Model.Matrix[a].Source)</td>
<td>@Html.TextAreaFor(x => Model.Matrix[a].Goal)</td>
<td>@Html.TextAreaFor(x => Model.Matrix[a].Frequency)</td>
<td>@Html.TextAreaFor(x => Model.Matrix[a].Distance)</td>
<td><input type="submit" name="+" class="btn btn-default" value="+" /></td>
<td><input type="submit" class="btn btn-default" value="-" /></td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" name="Speichern" value="Speichern" />
<input type="submit" class="btn btn-default" value="Speichern und weiter" />
<input type="button" class="btn btn-default" value="Weiter zu Schritt 5" onclick="@("window.location.href='" + @Url.Action("Q_Fifthpage", "Home") + "'");" />
</div>
</div>
</div>
</div>
}
获取方法:
[HttpGet]
public ActionResult Q_FourthPage()
{
// get current Questionnaire ID
int CurrentQstID = Convert.ToInt32(Session["qstid"]);
// create vm object. Capacity is a column in the table.
var Q4ViewModel = new ViewModels.Q4_Answer_VM();
// look for existing input data columns for this questionnaire in db
if (db.Capacities.Any(x => x.Questionnaire_ID == CurrentQstID))
{
// answers exist
Q4ViewModel.Matrix.AddRange(db.Capacities.Where(x => x.Questionnaire_ID == CurrentQstID));
}
else
{
// new capacity matrix
Q4ViewModel.TMatrix = db.QuestionTexts.Where(x => x.ID == 21).FirstOrDefault();
Q4ViewModel.Matrix = new List<Models.Capacity>();
}
var tmpcapacity = new Models.Capacity();
tmpcapacity.Questionnaire_ID = Convert.ToInt32(Session["qstid"]);
Q4ViewModel.Matrix.Add(tmpcapacity);
db.Capacities.Add(tmpcapacity);
db.SaveChanges();
return View(Q4ViewModel);
}
POST方法:
[HttpPost]
public ActionResult Q_FourthPage(ViewModels.Q4_Answer_VM vm)
{
int currentQst = Convert.ToInt32(Session["qstid"]);
if (Request.Form["+"] != null)
{
var tmpcapacity = new Models.Capacity();
tmpcapacity.Questionnaire_ID = currentQst;
vm.Matrix.Add(tmpcapacity);
db.Capacities.Add(tmpcapacity);
db.SaveChanges();
return View(vm);
}
if (Request.Form["Speichern"] != null)
{
// save data
if (!ModelState.IsValid) return View("~/Views/Shared/Error.cshtml");
var tmpcapacity = new Models.Capacity();
for (var a = 0; a < vm.Matrix.Count; a++)
{
var current = vm.Matrix[a];
current.ID = vm.Matrix[a].ID;
if (db.Capacities.Any(x => x.ID == current.ID))
// if clause never triggers true
// vm does not contain capacity ID
{
// column exists and is changed (or not)
tmpcapacity.Distance = vm.Matrix[a].Distance;
tmpcapacity.Frequency = vm.Matrix[a].Frequency;
tmpcapacity.Source = vm.Matrix[a].Source;
tmpcapacity.Goal = vm.Matrix[a].Goal;
tmpcapacity.Load = vm.Matrix[a].Load;
Models.Capacity c = db.Capacities.Where(x => x.ID == current.ID).FirstOrDefault();
c = tmpcapacity;
db.SaveChanges();
}
else
{
// new column
tmpcapacity.Distance = vm.Matrix[a].Distance;
tmpcapacity.Frequency = vm.Matrix[a].Frequency;
tmpcapacity.Source = vm.Matrix[a].Source;
tmpcapacity.Goal = vm.Matrix[a].Goal;
tmpcapacity.Load = vm.Matrix[a].Load;
tmpcapacity.Questionnaire_ID = currentQst;
db.Capacities.Add(tmpcapacity);
db.SaveChanges();
}
}
db.SaveChanges();
}
return View(vm);
}
如果您想 "save" object ID 并在 post 发生时取回它,您需要使用 .HiddenFor()
将其存储到隐藏字段中HTML 助手 - 类似这样的东西:
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.Object.Id);
<div class="container">
<div class="jumbotron">
然后,在你的 POST
上,你应该在你的 post body 中取回 Object.ID
并且你应该能够分辨出哪个 object这是为了.
如果需要将ID绑定到Model上,那么在使用Razor时需要在表单下使用hidden filed。
@Html.HiddenFor(model => model.Id)
更多详情
@using (Html.BeginForm("method", "ControllerName", FormMethod.Post))
{
@Html.HiddenFor(Model=>Model.ID)
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Button" />
</div>
</div>
}
现在您可以在您的控制器操作方法中访问 ID。
我的网站中有一个输入 table,它连接到一个视图模型。在控制器方法中,我将此视图模型传递给控制器,反之亦然,这意味着控制器使用数据库中的数据填充视图模型,视图 returns 填充用户可能输入的表单数据的视图模型.
问题是,一旦视图接收到视图模型对象,数据库中的 "ID" 属性就不再存在。调用 Post 方法时,无法知道必须更新哪个数据库条目。
我的问题是:当我将视图模型传递给控制器方法时,如何更新特定的数据库条目?
示例控制器方法:
[HttpPost]
public ActionResult method(ViewModel vm)
{
DataContext.Context.Where(x => x.ID == vm.Object.ID) // this is where vm.Object.ID always returns "0", not the actual ID from the database entry
Context.SaveChanges();
return View(vm);
}
如果您需要更多信息,请告诉我。此外,使用 jquery 不是该项目的可行选择。非常感谢您的帮助!
编辑:
查看:
@model MyANTon.ViewModels.Q4_Answer_VM
@{
ViewBag.Title = "myANTon Anforderungserfassung";
ViewBag.HideNavBar = false;
}
@using (Html.BeginForm())
{
<div class="container">
<div class="jumbotron">
<hr />
<table class="grid" id="datatable">
<tr>
<th>Nr.</th>
<th>Last</th>
<th>Quelle</th>
<th>Ziel</th>
<th>Frequenz [/h]</th>
<th>Abstand [m]</th>
<th></th>
<th></th>
@{int i = 1; }
@for (var a = 0; a < Model.Matrix.Count; a++)
{
<tr>
<td>@(i++)</td>
<td>@Html.TextBoxFor(x => Model.Matrix[a].Load)</td>
<td>@Html.TextAreaFor(x => Model.Matrix[a].Source)</td>
<td>@Html.TextAreaFor(x => Model.Matrix[a].Goal)</td>
<td>@Html.TextAreaFor(x => Model.Matrix[a].Frequency)</td>
<td>@Html.TextAreaFor(x => Model.Matrix[a].Distance)</td>
<td><input type="submit" name="+" class="btn btn-default" value="+" /></td>
<td><input type="submit" class="btn btn-default" value="-" /></td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" name="Speichern" value="Speichern" />
<input type="submit" class="btn btn-default" value="Speichern und weiter" />
<input type="button" class="btn btn-default" value="Weiter zu Schritt 5" onclick="@("window.location.href='" + @Url.Action("Q_Fifthpage", "Home") + "'");" />
</div>
</div>
</div>
</div>
}
获取方法:
[HttpGet]
public ActionResult Q_FourthPage()
{
// get current Questionnaire ID
int CurrentQstID = Convert.ToInt32(Session["qstid"]);
// create vm object. Capacity is a column in the table.
var Q4ViewModel = new ViewModels.Q4_Answer_VM();
// look for existing input data columns for this questionnaire in db
if (db.Capacities.Any(x => x.Questionnaire_ID == CurrentQstID))
{
// answers exist
Q4ViewModel.Matrix.AddRange(db.Capacities.Where(x => x.Questionnaire_ID == CurrentQstID));
}
else
{
// new capacity matrix
Q4ViewModel.TMatrix = db.QuestionTexts.Where(x => x.ID == 21).FirstOrDefault();
Q4ViewModel.Matrix = new List<Models.Capacity>();
}
var tmpcapacity = new Models.Capacity();
tmpcapacity.Questionnaire_ID = Convert.ToInt32(Session["qstid"]);
Q4ViewModel.Matrix.Add(tmpcapacity);
db.Capacities.Add(tmpcapacity);
db.SaveChanges();
return View(Q4ViewModel);
}
POST方法:
[HttpPost]
public ActionResult Q_FourthPage(ViewModels.Q4_Answer_VM vm)
{
int currentQst = Convert.ToInt32(Session["qstid"]);
if (Request.Form["+"] != null)
{
var tmpcapacity = new Models.Capacity();
tmpcapacity.Questionnaire_ID = currentQst;
vm.Matrix.Add(tmpcapacity);
db.Capacities.Add(tmpcapacity);
db.SaveChanges();
return View(vm);
}
if (Request.Form["Speichern"] != null)
{
// save data
if (!ModelState.IsValid) return View("~/Views/Shared/Error.cshtml");
var tmpcapacity = new Models.Capacity();
for (var a = 0; a < vm.Matrix.Count; a++)
{
var current = vm.Matrix[a];
current.ID = vm.Matrix[a].ID;
if (db.Capacities.Any(x => x.ID == current.ID))
// if clause never triggers true
// vm does not contain capacity ID
{
// column exists and is changed (or not)
tmpcapacity.Distance = vm.Matrix[a].Distance;
tmpcapacity.Frequency = vm.Matrix[a].Frequency;
tmpcapacity.Source = vm.Matrix[a].Source;
tmpcapacity.Goal = vm.Matrix[a].Goal;
tmpcapacity.Load = vm.Matrix[a].Load;
Models.Capacity c = db.Capacities.Where(x => x.ID == current.ID).FirstOrDefault();
c = tmpcapacity;
db.SaveChanges();
}
else
{
// new column
tmpcapacity.Distance = vm.Matrix[a].Distance;
tmpcapacity.Frequency = vm.Matrix[a].Frequency;
tmpcapacity.Source = vm.Matrix[a].Source;
tmpcapacity.Goal = vm.Matrix[a].Goal;
tmpcapacity.Load = vm.Matrix[a].Load;
tmpcapacity.Questionnaire_ID = currentQst;
db.Capacities.Add(tmpcapacity);
db.SaveChanges();
}
}
db.SaveChanges();
}
return View(vm);
}
如果您想 "save" object ID 并在 post 发生时取回它,您需要使用 .HiddenFor()
将其存储到隐藏字段中HTML 助手 - 类似这样的东西:
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.Object.Id);
<div class="container">
<div class="jumbotron">
然后,在你的 POST
上,你应该在你的 post body 中取回 Object.ID
并且你应该能够分辨出哪个 object这是为了.
如果需要将ID绑定到Model上,那么在使用Razor时需要在表单下使用hidden filed。
@Html.HiddenFor(model => model.Id)
更多详情
@using (Html.BeginForm("method", "ControllerName", FormMethod.Post))
{
@Html.HiddenFor(Model=>Model.ID)
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Button" />
</div>
</div>
}
现在您可以在您的控制器操作方法中访问 ID。