在ASP.NET mvc 5中更新列将创建新行
我将按照教程创建博客的修改版本。在这种情况下,“帖子”与“项目”是一样的,“标签”被称为“技术”,评论也是一样的。在这种情况下,“创建新职位/项目”功能还应能够更新现有职位/项目。但是,当我单击“提交”编辑一篇旧文章时,它只会创建一篇新文章 这是我的控制器:在ASP.NET mvc 5中更新列将创建新行,asp.net,asp.net-mvc,entity-framework,asp.net-mvc-5,Asp.net,Asp.net Mvc,Entity Framework,Asp.net Mvc 5,我将按照教程创建博客的修改版本。在这种情况下,“帖子”与“项目”是一样的,“标签”被称为“技术”,评论也是一样的。在这种情况下,“创建新职位/项目”功能还应能够更新现有职位/项目。但是,当我单击“提交”编辑一篇旧文章时,它只会创建一篇新文章 这是我的控制器: [Authorize] [HttpPost] [ValidateAntiForgeryToken] [ValidateInput(false)] public ActionResult Update(int? p, string title
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Update(int? p, string title, string shortDescription, string longDescription, DateTime dateTime, string technologies)
{
Project project = GetProject(p);
if (!User.IsInRole("ChapterAdvisor") || !(User.Identity.GetFirstName() + " " + User.Identity.GetLastName()).Equals(project.ProjectLeader))
{
RedirectToAction("Index");
}
project.Title = title;
project.ShortDescription = shortDescription;
project.LongDescription = longDescription;
project.TimeCreated = dateTime;
project.ProjectLeader = User.Identity.GetFirstName() + " " + User.Identity.GetLastName();
project.Technologies.Clear();
technologies = technologies ?? string.Empty;
string[] technologyNames = technologies.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
foreach (string technologyName in technologyNames)
{
project.Technologies.Add(GetTechnology(technologyName));
}
if (!p.HasValue)
{
model.Projects.Add(project);
}
try
{
model.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
Exception raise = dbEx;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
string message = string.Format("{0}:{1}",
validationErrors.Entry.Entity.ToString(),
validationError.ErrorMessage);
// raise a new exception nesting
// the current instance as InnerException
raise = new InvalidOperationException(message, raise);
}
}
throw raise;
}
return RedirectToAction("Details", new { p = project.Id });
}
public ActionResult Edit(int? p)
{
Project project = GetProject(p);
StringBuilder technologyList = new StringBuilder();
foreach (Technology technology in project.Technologies)
{
technologyList.AppendFormat("{0} ", technology.Name);
}
ViewBag.Technologies = technologyList.ToString();
return View(project);
}
private Technology GetTechnology(string technologyName)
{
return model.Technologies.Where(x => x.Name == technologyName).FirstOrDefault() ?? new Technology() { Name = technologyName };
}
private Project GetProject(int? id) => id.HasValue ? model.Projects.Where(x => x.Id == id).First() : new Project() { Id = -1 };
这是我的观点:
<form action="@Href("~/Projects/Update")" method="post" id="postForm">
@Html.AntiForgeryToken()
@if (Model.Id != -1)
{
<input type="hidden" value="@Model.Id" />
}
@{ DateTime dateTime = Model.TimeCreated.Year > 2000 ? Model.TimeCreated : DateTime.Now; }
<input type="text" name="dateTime" value="@dateTime" /> Date<br />
<input type="text" name="title" value="@Model.Title" /> Project Name<br />
@Html.DropDownListFor(m => m.Technologies, new SelectList(new List<Object> { new { value = "Animation", text = "Animation" }, new { value = "Robotics", text = "Robotics" }, new { value = "Architecture", text = "Architecture" }, new { value = "CAD", text = "CAD" }, new { value = "Websites", text = "Websites" }, new { value = "Games", text = "Games" }, new { value = "Biotechnology", text = "Biotechnology" }, new { value = "Club", text = "Club" }, new { value = "Other", text = "Other" } }, "value", "text"), new { @style = "border: 1px solid #e8e8e8;padding: 0.5em 1.07em 0.5em;background: #f5f5f5;font-size: 0.875rem;border-radius: 5px;width: 100%;line-height: 1.43;min-height: 3.5em;" })
<textarea name="shortDescription" rows="5" cols="80">@Model.ShortDescription</textarea><br />
<textarea name="longDescription" rows="10" cols="80">@Model.LongDescription</textarea><br />
<input type="submit" name="submit" value="Save Changes" />
</form>
@Html.AntiForgeryToken()
@如果(Model.Id!=-1)
{
}
@{DateTime DateTime=Model.TimeCreated.Year>2000?Model.TimeCreated:DateTime.Now;}
日期
项目名称
@DropDownListFor(m=>m.Technologies,new SelectList(new List{new{value=“Animation”,text=“Animation”},new{value=“Robotics”,text=“Robotics”},new{value=“Architecture”,text=“Architecture”},new{value=“CAD”,text=“CAD”},new{value=“Websites”,text=“Websites”},new{value=“Games”,text=“Games”},new{value=“Biotechnology”,text=“Biotechnology”},new{value=“Club”,text=“Club”},new{value=“Other”,text=“Other”},“value”,“text”),new{@style=“border:1px solid#e8e8e8;padding:0.5em 1.07em 0.5em;background:#f5f5f5f5;字体大小:0.875rem;边框半径:5px;宽度:100%;线条高度:1.43;最小高度:3.5em;“})
@型号。简短说明
@型号.说明
你知道为什么它要创建一个新的“项目”而不是更新url中传递的变量定义的项目吗?该表单中的每个帖子都被视为一个“新”记录,因为它不包含现有记录中的ID。因此逻辑总是假定它是新的 这是因为隐藏的输入没有包含在POST数据中,因为它没有
名称
:
<input type="hidden" value="@Model.Id" />
看起来您的操作希望ID值被称为“p”:
或者,由于OP已经在使用helpers:@Html.HiddenFor(m=>m.Id)
@DavidG:name属性仍然需要显式指定,因为这将创建一个名为Id
的输入。哦,我甚至没有发现!也许我应该睡觉了:)
<input type="hidden" name="p" value="@Model.Id" />