ASP.NET MVC3 ActionResult Edit не сохраняет изменения в базе данных - PullRequest
0 голосов
/ 13 марта 2012

У меня проблема с редактированием данных в контроллере. Две мои модели выглядят так:

[Table("Zielgruppen")]
public class Zielgruppe
{
    public int Id { get; set; }
    public string Zielgruppenname { get; set; }
    public Bezug Bezug { get; set; }
}

и

public class Bezug
{
    public int Id { get; set; }
    public string Bezugsname { get; set; }
}

Функции в моем контроллере:

public ActionResult Edit(int id)
{
    Zielgruppe zielgruppe = _db.Zielgruppe.Include("Bezug").Single(z => z.Id == id);
    ViewBag.BezugsId = new SelectList(_db.Bezug, "Id", "Bezugsname", zielgruppe.Bezug.Id);
    return View(zielgruppe);
}

[HttpPost]
public ActionResult Edit(Zielgruppe aktualisierteZielgruppe)
{
    if(ModelState.IsValid)
    {
        aktualisierteZielgruppe.Bezug = _db.Bezug.Find(aktualisierteZielgruppe.Bezug.Id);
        _db.Entry(aktualisierteZielgruppe).State = EntityState.Modified;
        _db.SaveChanges();
        return RedirectToAction("Index");
    }
    ViewBag.BezugsId = new SelectList(_db.Bezug, "Id", "Bezugsname", aktualisierteZielgruppe.Bezug.Id);
    return View();            
}

Моя проблема в том, что если я изменю aktualisierteZielgruppe.Bezug, изменения не сохранятся в базе данных.

и это мой edit.cshtml:

@model Medien_Archiv.Models.Zielgruppe

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Zielgruppe</legend>

        @Html.HiddenFor(model => model.Id)

        <div class="editor-label">
            @Html.LabelFor(model => model.Zielgruppenname)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Zielgruppenname)
            @Html.ValidationMessageFor(model => model.Zielgruppenname)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Bezug)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.Bezug.Id, ViewBag.BezugsId as SelectList)   
        </div>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Ответы [ 4 ]

1 голос
/ 13 марта 2012

Сложно сказать по вашему коду, но похоже, что вы загружаете объект из базы данных на основе идентификатора, возвращаемого из представления, устанавливая его состояние в значение Modified и затем сохраняя тот же объект.

Не похоже, что вы фактически устанавливаете свойства из представления обратно к объекту перед сохранением его в базе данных.Какой ORM вы используете?Большинство ORM обрабатывают состояние объекта, когда каждое свойство модифицируется, и по существу устанавливают свое собственное состояние в значение Modified, когда оно фиксируется.

Установите точку останова перед загрузкой объекта из базы данных, быстро наблюдайте за поступающими значениямиВернитесь из вида и затем быстро просмотрите их после загрузки из базы данных. Я думаю, вы обнаружите, что перезаписали их

0 голосов
/ 07 февраля 2016

Это был первый результат от Google, поэтому я оставляю здесь свои комментарии на случай, если я смогу сохранить головную боль для кого-то другого.

Вот что произошло в моем случае. Я создал свою модель и создал все необходимые виды с помощью строительных лесов. Затем я вернулся и добавил внешний ключ к своей модели.

Несмотря на то, что в представлении индекса и редактирования перечислены все поля, которые я вложил, внешнему ключу не было присвоено значение. Это привело к тому, что context.SaveChanges () никогда не выполнялся, так как ModelState был недействительным.

В обход внешнего ключа, как показано ниже, проблема была решена.

@Html.HiddenFor (model => model. ForeignKey )

0 голосов
/ 13 августа 2012

Если вы передаете коллекцию FormCollection, как в одном из приведенных выше примеров, вы можете изменить ее значения и затем переназначить FormCollection на ValueProvider перед вызовом TryUpdateModel (), например, так:

this.ValueProvider = collection.ToValueProvider();

Однако, если вы передаете Объект, как Zielgruppe, я не знаю - пытаясь выяснить это сам.

0 голосов
/ 13 марта 2012

Это один из случаев, когда структура сущности дает сбой - отслеживание обновленных ассоциаций.

Я предполагаю, что вы не делаете здесь какую-либо причудливую привязку модели (то есть привязку модели из базы данных).

if(ModelState.IsValid)
{
    aktualisierteZielgruppe.Bezug = _db.Bezug.Find(aktualisierteZielgruppe.Bezug.Id);

    // The problem is here.  EF doesn't mark associations as modified
    // the same way it tracks scalar types.
    _db.Entry(aktualisierteZielgruppe).State = EntityState.Modified;
    _db.SaveChanges();
    return RedirectToAction("Index");
}

Вот более традиционный способ:

[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
    // Get the original record to edit from the database.
    var gruppe = _db.Zielgruppe.Include("Bezug").Single(z => z.Id == id);

    // This will attempt to do the model binding and map all the submitted 
    // properties to the attached entity.
    if (TryUpdateModel(grupppe))
    {
        _db.SaveChanges();
        return RedirectToAction("Index");
    }
}

Также обратите внимание, что этот метод привязки к сущностям оставляет вас открытым для чрезмерной публикации атак. Вы можете уменьшить этот вектор атаки с помощью свойств модели белого списка во время привязки модели или привязки к модели представления и затем карта.

...