【问题标题】:Updating column in ASP.NET mvc 5 creates new row在 ASP.NET mvc 5 中更新列会创建新行
【发布时间】:2017-09-17 23:51:54
【问题描述】:

我正在关注this 教程来创建博客的修改版本。在这种情况下,“帖子”与“项目”是相同的东西,“标签”称为“技术”,而 cmets 都是相同的。在这种情况下,创建新的帖子/项目功能也应该能够更新现有的帖子/项目。然而,当我点击提交,编辑旧帖子时,它只是创建了一个新帖子。

这是我的控制器:

[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>

任何想法为什么它创建一个新的“项目”而不是更新由 url 中传递的变量定义的项目?

【问题讨论】:

    标签: asp.net asp.net-mvc entity-framework asp.net-mvc-5


    【解决方案1】:

    该表单中的每个帖子都被视为“新”记录,因为它不包含现有记录中的 ID。所以逻辑总是假设它是新的。

    这是因为隐藏的输入没有包含在 POST 数据中,因为它没有name

    <input type="hidden" value="@Model.Id" />
    

    看起来您的操作需要将 ID 值称为“p”:

    <input type="hidden" name="p" value="@Model.Id" />
    

    【讨论】:

    • 或者,由于 OP 已经在使用助手:@Html.HiddenFor(m =&gt; m.Id)
    • @DavidG:name 属性仍然需要明确指定,因为这会创建一个名为 Id 的输入。
    • 哦,我什至没有发现!也许是我应该去睡觉的迹象:)
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    相关资源
    最近更新 更多